Nodejs CORS 中的POST and OPTIONS 请求

Nodejs CORS 中的POST and OPTIONS 请求

  var req = new XMLHttpRequest();
req.open(‘post’, ‘http://127.0.0.1:3001/user’, true);
req.setRequestHeader(‘Content-Type’, ‘application/json’);
req.send(’{“name”:“tobi”,“species”:“ferret”}’);

此Ajax 跨域访问post 请求,但是在服务器却得到的总是options请求 (req.method==‘OPTIONS’) 不知为何啊?


5 回复

当涉及到跨源资源共享(CORS)时,浏览器会自动发送一个预检请求(OPTIONS 请求),以确定实际的 POST 请求是否安全执行。如果服务器响应中包含正确的 CORS 头信息,则浏览器才会允许实际的 POST 请求发送。

示例代码

假设你有一个 Node.js 应用,并且使用 Express 框架来处理 HTTP 请求。你需要配置 CORS 以便正确处理 POSTOPTIONS 请求。

首先,确保安装了 cors 中间件:

npm install cors

然后,在你的应用中进行如下配置:

const express = require('express');
const cors = require('cors');

const app = express();

// 使用 cors 中间件
app.use(cors());

// 定义一个 POST 路由
app.post('/user', (req, res) => {
  console.log(req.body); // {"name":"tobi","species":"ferret"}
  res.status(200).json({ message: "User created successfully" });
});

// 启动服务器
app.listen(3001, () => {
  console.log('Server is running on port 3001');
});

解释

  1. 预检请求 (OPTIONS):

    • 浏览器会先发送一个 OPTIONS 请求,询问服务器是否允许跨域请求。
    • 通过配置 cors 中间件,Express 会自动处理这些预检请求,并添加必要的 CORS 头信息,如 Access-Control-Allow-Origin, Access-Control-Allow-Methods 等。
  2. 实际的 POST 请求:

    • 如果预检请求成功,浏览器将发送实际的 POST 请求。
    • 在上述代码中,/user 路由会处理这个 POST 请求,并返回一个 JSON 响应。

问题分析

如果你始终收到 OPTIONS 请求,可能是因为:

  • 服务器没有正确配置 CORS。
  • 客户端代码没有正确设置 Content-Type 或其他必要的头信息。
  • 浏览器缓存或网络问题。

通过以上配置,你应该能够解决 OPTIONS 请求的问题,并正常处理 POST 请求。


哦, 知道了. 因为此post请求的 content-type不是one of the “application/x-www-form-urlencoded, multipart/form-data, or text/plain”, 所以Preflighted requests被发起。 “preflighted” requests first send an HTTP OPTIONS request header to the resource on the other domain, in order to determine whether the actual request is safe to send. 然后得到服务器response许可之后, res.set(‘Access-Control-Allow-Origin’, ‘http://127.0.0.1:3000’); res.set(‘Access-Control-Allow-Methods’, ‘GET, POST, OPTIONS’); res.set(‘Access-Control-Allow-Headers’, ‘X-Requested-With, Content-Type’); 再发起其post请求。 https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

此例子是从3000端口域向3001端口域发request.

其实这里还存在一个问题,如果服务器不支持 prefight 的 options 请求,这个请求也会死掉。 http://hi.barretlee.com/2014/08/19/post-method-change-to-options/

在Node.js中处理CORS(跨源资源共享)时,经常会遇到浏览器发送预检OPTIONS请求的情况。这是由于浏览器的安全策略,对于非简单请求(例如包含自定义头部或使用POST方法),会先发送一个OPTIONS请求以检查服务器是否允许该请求。

为了解决这个问题,你需要在你的Node.js服务器上设置适当的CORS头。这里有一个简单的示例,展示如何使用Express框架来处理这个问题:

const express = require('express');
const cors = require('cors');

const app = express();

// 使用cors中间件,并配置允许所有来源
app.use(cors());

// 处理POST请求
app.post('/user', (req, res) => {
    console.log(req.body); // 输出请求体
    res.status(200).send({ message: "POST request received successfully." });
});

// 监听端口
app.listen(3001, () => {
    console.log('Server is running on port 3001');
});

在这个例子中,我们使用了cors中间件,它会自动添加必要的CORS头到每个响应中,使得任何来源的POST请求都可以被接收。如果你需要更细粒度地控制CORS策略,可以传入cors中间件选项,例如限制特定的来源、允许的方法等。

如果你不希望使用第三方库,也可以手动添加这些CORS头:

app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*'); // 允许所有来源
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); // 允许的方法
    if (req.method === 'OPTIONS') {
        return res.status(200).end(); // 预检请求返回200状态码
    }
    next();
});

这段代码首先设置了基本的CORS头,然后针对OPTIONS请求直接返回一个200状态码。这样就可以避免实际的POST请求没有被执行的错误。

通过这种方式,你可以确保你的Node.js应用正确处理了CORS相关的POSTOPTIONS请求。

回到顶部