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’) 不知为何啊?
当涉及到跨源资源共享(CORS)时,浏览器会自动发送一个预检请求(OPTIONS
请求),以确定实际的 POST
请求是否安全执行。如果服务器响应中包含正确的 CORS 头信息,则浏览器才会允许实际的 POST
请求发送。
示例代码
假设你有一个 Node.js 应用,并且使用 Express 框架来处理 HTTP 请求。你需要配置 CORS 以便正确处理 POST
和 OPTIONS
请求。
首先,确保安装了 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');
});
解释
-
预检请求 (
OPTIONS
):- 浏览器会先发送一个
OPTIONS
请求,询问服务器是否允许跨域请求。 - 通过配置
cors
中间件,Express 会自动处理这些预检请求,并添加必要的 CORS 头信息,如Access-Control-Allow-Origin
,Access-Control-Allow-Methods
等。
- 浏览器会先发送一个
-
实际的
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/