预期
发送Content-Type为application/json的post请求不触发跨域错误
- 客户端请求
const params = {
a: 'a',
b: 'b',
}
//直接发送对象则Content-Type为application/json
axios.post(API_URL, params)
.then((res) => {
console.log(res)
})
- 后端配置
如果请求为简单请求则不会出发 CORS 预检请求,可直接在请求内配置Access-Control-Allow-Origin,Access-Control-Allow-Methods,Access-Control-Allow-Headers,来解决跨域问题
// 简单请求
app.get('/API',(req,res,next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
...
})
如果Content-Type 的值仅限于下列三者之一视为简单请求:
text/plain
multipart/form-data
application/x-www-form-urlencoded
本例Content-Type为application/json,则不属于简单请求,需要先发送预检请求,所有直接在请求内设置以下配置是无效的.
设置了Access-Control-Allow-Origin", "*", 仍然会报错:
Access to XMLHttpRequest at 'http://localhost:portA/API' from origin 'http://localhost:portB' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
app.post('/API',(req,res,next) => {
// res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
// res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
//无效
...
})
nodejs 解决方案
当触发预检请求时让options请求快速结束,直接执行请求
const express = require("express");
const app = express();
//跨域配置需放在接口前面
app.use("/API", (req,res,next) => {
console.log('checking');
//设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin","http://localhost:port");
//允许的header类型
res.header("Access-Control-Allow-Headers","content-type");
//跨域允许的请求方式
res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
if (req.method.toLowerCase() == 'options')
res.send(200); //让options尝试请求快速结束
else
next();
})
app.get('/API',(req,res,next) => {...})
//或者
app.post('/API',(req,res,next) => {...})