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);
        });

求解决方法


8 回复

因为你这里单独接口的时候没有对 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-TypeAccept 等。如果你添加了自定义头部,比如 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 请求包含自定义头部时也应该能够正常跨域。

回到顶部