Node.js:POST - 请求方法:选项状态代码:403 Forbidden

时间:2018-03-29 18:14:09

标签: node.js express post axios http-status-code-403

我们有以下设置:

Front end code : REACT (Hosted using express js) (lets call this www.domainA.com)
Backend        : .NET WEB API (Hosted in IIS 7.5) (lets call this www.domainB.com)

FE应用程序的域正在向Web api发出GET数据和POST数据的请求。

GET工作正常,但每当我尝试将数据发布到Web API时,都会抛出以下错误:

Request URL: http://www.domainB.com/api/postdataoperation
Request Method: OPTIONS
Status Code: 403 Forbidden

我查看了许多CORS文章,并继续在IIS中设置HTTPResponseHeaders,如下所示:

Access-Control-Allow-Methods : POST,GET,OPTIONS,PUT,DELETE
Access-Control-Allow-Origin  : http://www.domainA.com

反应解决方案的发布请求如下:

axios.post(`http://www.domainB.com/api/postdataoperation`, {userId});

3 个答案:

答案 0 :(得分:4)

问题是您的服务器未配置为以正确的响应状态 2xx成功状态响应 OPTIONS 请求。

GET正在运行,因为它没有发出预检请求,因为它符合simple request

定义的CORS documentation标准

另一方面,POST请求符合条件Preflighted request,这意味着应首先进行预检OPTIONS请求。

简而言之,您已正确设置了CORS响应标头,但服务器未配置为响应OPTIONS方法请求的 2xx响应(通常为200状态)。

  

服务器必须以2xx成功状态(通常为200或204)响应OPTIONS请求。

     

如果服务器不这样做,那么它配置为发送的Access-Control- *标头没有区别。配置服务器以正确方式处理OPTIONS请求的答案 - 发送200或204成功消息 - 取决于它运行的服务器软件

this answer借用解决方案,在你的后端.NET WEB API上执行此操作:

BaseApiController.cs

我们这样做是为了允许OPTIONS http动词

public class BaseApiController : ApiController
  {
    public HttpResponseMessage Options()
    {
      return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
    }
}

参考

Preflighted requests

response for preflight 403 forbidden

注意

在domainA.com上运行nodejs服务器是无关紧要的。 "axios"库可以用于a)从浏览器生成XMLHttpRequests或b)从node.js发出http请求。在这种情况下,它是第一个选项," axios.post"到domainB是通过浏览器的 XMLHttpRequest 完成的,这就是你在domainB.com上获得预检请求的原因。

答案 1 :(得分:0)

POST请求失败时.NET Web API的输出是什么?

答案 2 :(得分:0)

Jannes Botis的回答很好地解释了Preflighted机制。我只是添加了我用来解决Node.js / Express

上的这个问题的代码
const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', 'http://www.domainA.com');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
  res.setHeader(
    'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept, Authorization'
  );
  next();
});

// All OPTIONS requests return a simple status: 'OK'
app.options('*', (req, res) => {
  res.json({
    status: 'OK'
  });
});

app.get('/', ...);

app.post('/api/postdataoperation', ...);