【问题标题】:Why do I keep getting a status code 403 in a http request even after adding CORS?为什么即使添加了 CORS,我仍然在 http 请求中收到状态代码 403?
【发布时间】:2016-09-10 06:39:44
【问题描述】:

当我尝试在应用程序前端的 Angular 中发出 http 请求时,我无法完成请求,因为我在预检请求中获得状态代码 403。我已经在后端的 Node.js 中设置了标题以允许访问,但对于 GET 或 POST 请求,我仍然收到错误消息。我也在这里阅读了一些答案,他们基本上说将标头 Access-Control-Allow-Origin 设置为 *,但这不起作用。

这是我的前端:

 $http({
        method : "GET",
        url : "http://localhost:8080/v1/get-mac",
        headers: {
            'Content-Type': "application/json",
            'Authorization': "token"
        }
        }).then(function(response) {
            this.machines = response.data;
        });

这就是我在后端使用 Express 所做的:

app.use(function(req, res, next){
  res.header('Access-Control-Allow-Origin', "*");
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.header('Access-Control-Allow-Methods', 'GET, POST');
  next();
});

我在 Chrome 中遇到的错误是:

OPTIONS http://localhost:8080/v1/get-mac
  (anonymous function) @ angular.js:12011
  sendReq @ angular.js:11776
  serverRequest @ angular.js:11571
  processQueue @ angular.js:16383
  (anonymous function) @ angular.js:16399
  $eval @ angular.js:17682
  $digest @ angular.js:17495
  $apply @ angular.js:17790
  (anonymous function) @ angular.js:25890
  defaultHandlerWrapper @ angular.js:3497
  eventHandler @ angular.js:3485
XMLHttpRequest cannot load http://localhost:8080/v1/get-mac    
  Response for preflight has invalid HTTP status code 403

为什么会这样?已经尝试了很多东西,但我不知道为什么即使设置了响应头它也不起作用。谢谢

这是我的 app.js:

var server = require(__dirname + '/server.js')();

var app = server.app.express();

app.use(function(req, res, next){
  res.header('Access-Control-Allow-Origin', "*");
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.header('Access-Control-Allow-Methods', 'GET, POST');
  next();
});

app.use(server.app.express.static(server.app.path.join(__dirname, 'views')));
app.use(server.app.morgan('dev'));
app.engine('html', server.app.ejs.renderFile);
app.set('view engine', 'ejs');
app.use(server.app.methodOverride());
app.use(server.app.bodyParser.urlencoded({ extended: false }));
app.use(server.app.bodyParser.json());

server.router(app);

return server.app.http.createServer(app).listen(process.env.PORT || 8080, function() {
  console.log("Server is on, listening on: 8080");
});

【问题讨论】:

  • 为什么您的后端服务器代码以 403 响应 OPTIONS 请求?让您的服务器使用 200 响应来响应 OPTIONS 请求。您还没有显示任何会导致 403 响应的后端代码,所以我无法告诉您如何在您的代码中修复它。
  • 换一种说法:您似乎认为 CORS 标头以某种方式导致了 403 响应,但最终的事实是 403 响应导致了 CORS 失败。修复您的服务器代码,使其在收到 OPTIONS 请求时不响应 403,并且您的客户端 CORS 错误将消失。
  • 你为什么有'Content-Type': "application/json",?您正在发出 GET 请求。没有内容可以描述的类型。

标签: angularjs node.js http xmlhttprequest


【解决方案1】:

服务器应向 OPTIONS 请求发送“200”响应。 所以修改你的服务器代码:

app.use(function(req, res, next){
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Headers', 'Content-Type,     
                                               Authorization');
    res.header('Access-Control-Allow-Methods', 'GET, POST');
    if(req.method === 'OPTIONS'){
        return res.status(200)
    }
    next();
});

【讨论】:

  • 如果请求的原点与当前页面的原点不同,那么你应该如何指定目标原点呢?如果 OP 的代码在 example.com 的页面中,并且您想要发送对 http://localhost:8080/v1/get-mac 的请求,那么您需要指定您的目标是 localhost:8080somewhere
  • 查看编辑后的答案。 Luiz 得到的错误不是来自服务器,而是来自浏览器。如果没有设置这些标头,浏览器将不允许任何 CORS 请求通过
  • 致您的编辑:这正是 OP 的代码已经在做的事情;发送跨域请求时,浏览器会自动添加 CORS 标头。
  • 错误来自浏览器,但浏览器正在产生错误,因为服务器正在使用 403 响应响应 CORS OPTIONS 预检,从而以错误状态终止请求。这里的解决方案是“阻止服务器发送 403 响应”。 (请参阅preflight steps of the CORS spec,其中包括说明“如果响应的 HTTP 状态代码不在 2xx 范围内:应用网络错误步骤。”)
  • 是的,我意识到我的错误。
猜你喜欢
  • 2021-07-14
  • 2021-10-03
  • 1970-01-01
  • 2021-06-28
  • 2022-01-25
  • 2019-04-02
  • 2023-01-29
  • 1970-01-01
  • 2016-12-02
相关资源
最近更新 更多