Nodejs koa2 给某条特定的 url 设置 cors 后,前端 ajax 自定义头部后就无法跨域,去掉头部就能跨域
Nodejs koa2 给某条特定的 url 设置 cors 后,前端 ajax 自定义头部后就无法跨域,去掉头部就能跨域
app.js
const Koa = require('koa');
const Router = require('koa-router');
const router = new Router();
const app = new Koa();
router.all('*',function (ctx, next) {
ctx.set('Access-Control-Allow-Origin', '*');
ctx.set('Access-Control-Allow-Headers', 'Content-Type, myheader');
ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
next();
});
router.post('/api/test/', (ctx, next) => {
ctx.body = {
status: 'success'
}
});
router.post('/api/test2/', (ctx, next) => {
ctx.body = {
status: 'success'
}
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(8089);
console.log('server start at 8089')
前端自定义头部myheader
axios.post(`http://localhost:8089/api/test`, null, { headers: { 'myheader': 'test' }})
.then(response => {
console.log(response.data);
});
后台把所有的接口都设置成 cors,前端是可以自定义头部的。
但是如果我只是让其中一个接口 cors
const Koa = require('koa');
const Router = require('koa-router');
const router = new Router();
const app = new Koa();
router.post(’/api/test/’, (ctx, next) => {
ctx.set(‘Access-Control-Allow-Origin’, ‘*’);
ctx.set(‘Access-Control-Allow-Headers’, ‘Content-Type, myheader’);
ctx.set(‘Access-Control-Allow-Methods’, ‘PUT, POST, GET, DELETE, OPTIONS’);
ctx.body = {
status: ‘success’
}
});
router.post(’/api/test2/’, (ctx, next) => {
ctx.body = {
status: ‘success’
}
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(8089);
console.log(‘server start at 8089’)
这时前端设置自定义头部,就会报错
说没有
No 'Access-Control-Allow-Origin' header
,但是我已经设置过Access-Control-Allow-Headers
了。
如果前端把自定义头部去掉,这时又能跨域成功
// 正常跨域
axios.post(`http://localhost:8089/api/test`)
.then(response => {
console.log(response.data);
});
求解决方法
因为你这里单独接口的时候没有对 option 请求做出响应
嗯,就是这个原因
但是为啥单独接口的时候,我不加自定义头部,虽然没对 option 做响应,但是也跨域成功了?
我没看错的话你代码不是就是这个意思吗……上面的代码是 router.all ,下面是 post (“ api/test ”)
详细看看跨域控制协议吧,只有 simple request 不会发预置 options 请求,而它是有限制的(比如只能报告某些头部)。
因为这里不带自定义头部不需要 option 请求,具体参考同源策略和跨域协商的细节
router.post(’/api/test/’, (ctx, next) => {
ctx.set(‘Access-Control-Allow-Origin’, ‘*’);
ctx.set(‘Access-Control-Allow-Headers’, ‘Content-Type, myheader’);
ctx.set(‘Access-Control-Allow-Methods’, ‘PUT, POST, GET, DELETE, OPTIONS’);
ctx.body = {
status: ‘success’
}
});
你这里处理了post
请求啊,你要把post
改成all
。在你没有单独拦截接口的时候,你用的是all
,当然包括了option
在 Node.js 中使用 Koa2 设置 CORS(跨域资源共享)时,如果你发现只有在前端 AJAX 请求包含自定义头部时才会出现跨域问题,这通常是因为 CORS 配置没有正确允许这些自定义头部。
默认情况下,CORS 中间件可能只允许一些常见的头部,如 Content-Type
、Accept
等。如果你添加了自定义头部,比如 X-Custom-Header
,你需要在 CORS 配置中显式允许这些头部。
以下是一个示例,展示如何在 Koa2 中使用 @koa/cors
中间件来允许特定的 URL 和自定义头部:
const Koa = require('koa');
const cors = require('@koa/cors');
const app = new Koa();
// 设置 CORS,允许特定的 URL 和自定义头部
app.use(cors({
origin: 'http://your-frontend-origin.com', // 替换为你的前端域名
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowHeaders: ['Content-Type', 'X-Requested-With', 'X-Custom-Header'], // 添加自定义头部
}));
app.use(async ctx => {
if (ctx.path === '/your-specific-url') {
ctx.body = 'Hello from your specific URL!';
} else {
ctx.body = 'Hello World!';
}
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
确保 origin
设置为你的前端域名,allowHeaders
中包含所有你需要的自定义头部。这样配置后,前端 AJAX 请求包含自定义头部时也应该能够正常跨域。