node server响应头设置允许跨域,却仍然存在跨域问题的解决方案

RyanWu -
node server响应头设置允许跨域,却仍然存在跨域问题的解决方案
案例

今天在做全栈的练习项目时,发现在发POST请求时,存在跨域问题(server的header设置了允许跨域),server大概如下

const express = require('express')
const app = express()
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.post('/login', (request, response) => {
    //允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    response.setHeader('Access-Control-Allow-Headers','*');
    response.send('Hello')
})

前端是用axios发送的ajax请求,这里会有一点影响,但是重点不在这,所以这里不贴代码。

原因分析

点开浏览器的network调试界面,发现除了post请求还有一个options请求,然后看看console里的报错信息

Access to XMLHttpRequest at 'http://127.0.0.1:8000/login' from origin 'http://localhost:3000' 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.

果然发现是preflight request的问题,也就是这个options请求的跨域没有通过。

那又为什么会有这个preflight呢?参考CORS文档发现有这三种情况会发送预请求:

请求方法不是GET/POST/HEAD设置了默认请求头意外的自定义请求头

POST请求中的content-type不是

application/x-www-form-urlencodedmultipart/form-datatext/plain

然而我们所用的axios发送的请求默认的content-type是application/json,所以理所当然需要去发送这个预请求,那么只需要让这个预请求跨域通过就好了

解决方案

server改路由规则(post->all)
最暴力的方法,直接将跨域给到all请求类型,所以预请求的options肯定是能够跨域的

app.all('/login', (request, response) => {
 //允许跨域
 response.setHeader('Access-Control-Allow-Origin','*')
 response.setHeader('Access-Control-Allow-Headers','*');
 response.send('Hello')
})

添加一个options的路由规则
这个就是对症下药的方法,在下方单独添加一条新的规则,使用options请求类型

app.post('/login', (request, response) => {
 //允许跨域
 response.setHeader('Access-Control-Allow-Origin','*')
 response.setHeader('Access-Control-Allow-Headers','*');
 response.send('Hello')
})
app.options('/login', (request,response) => {
 response.setHeader("Access-Control-Allow-Origin","*")
 response.setHeader("Access-Control-Allow-Headers", "*");
 response.end()
})
特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。

Tags 标签

ajax跨域node.jsaxiosajax

扩展阅读

加个好友,技术交流

1628738909466805.jpg