【问题标题】:Node.js : POST - Request Method: OPTIONS Status Code: 403 ForbiddenNode.js:POST - 请求方法:OPTIONS 状态代码:403 Forbidden
【发布时间】:2018-09-08 19:11:07
【问题描述】:

我们有以下设置:

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

react 解决方案的 post 请求如下:

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

【问题讨论】:

  • 所以我理解正确,您在 IIS 中托管节点服务器?
  • @TheIncorrigible1 很抱歉错过了 FE 托管在 Express 上的详细信息(更新)
  • 您在浏览器控制台中看到了什么?它会给您一个错误,告诉您请求/CORS 标头的问题所在。请将该信息添加到您的问题中,因为它对解决方案至关重要
  • 你在用csrf_token吗?
  • 你写过Node.js服务器吗?如果是,那么您能否与我们分享接受GETPOST 请求的路线部分。这将更清楚问题是什么。此外,您可以查看Node.js 服务器日志,以找到确切的错误。

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


【解决方案1】:

问题在于您的服务器未配置为以正确的响应状态(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) 从浏览器发出 XMLHttpRequest 或 b) 从 node.js 发出 http 请求。在这种情况下,它是第一个选项,到 domainB 的“axios.post”是通过来自浏览器的 XMLHttpRequest 完成的,这就是为什么您会在 domainB.com 获得 预检请求。

【讨论】:

    【解决方案2】:

    Jannes Botis 的回答很好地解释了预检机制。我只是在 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', ...);
    

    【讨论】:

      猜你喜欢
      • 2016-01-18
      • 2018-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-25
      • 2021-10-05
      • 1970-01-01
      • 2019-03-24
      相关资源
      最近更新 更多