egg设置中间件后返回404,报cors跨域错误

现象:

  • 本地调试(同源请求)发现,接口返回404
  • 测试环境 (跨域请求) 发现报cors跨域错误
  • 部分接口能请求成功,部分接口请求失败(404或跨域报错)

原因

为什么返回404

      中间件参数中有个next函数,需要使用await调用,若省略await,且接口函数是异步的,会直接返回,而没有真正执行到接口函数,ctx的response默认内容就是404,所以同源请求会返回404

为什么配置了跨域还会跨域报错呢?

     这是因为,跨域时会发起preflight请求(预检请求),preflight请求成功即认为允许跨域,否则报跨域错误,并且preflight只允许2xxx返回码,重定向返回3xx也会认为是错误;
     我后台配置了https,并且设置了自动将http请求重定向至https,而前端是用http请求的,所以返回了302重定向,preflight认为失败了,所以会报cors错误

为什么部分接口成功,部分失败

     如果接口函数是同步执行的,那么用不用await都是没有影响的,所以同步执行的接口函数都会成功,而异步执行的都会失败

分析过程

  • F12查看网络请求状态,发现有一个明明注册了路由的接口返回了404,而其他部分接口却返回了正常
  • 因为最新的改动就是增加了该接口,并且添加了中间件,尝试去除中间件,发现接口可以正常访问
  • 通过打log发现,中间件逻辑是正常的,没有问题
  • 详细查log发现,接口是可以请求到一次的(preflight请求,正式请求会报cors),但是接口返回的结果依然是404
  • 反应过来,ctx的response默认status就是404,猜测是不是body没填充,然后想起来,next其实就是调用新写的接口,新写的接口是异步的,next直接调用能不能执行异步逻辑呢,显然是不行的,尝试加上await后,一切恢复正常

中间件内容

export default (/*options: any, app: Application*/) => {
    
    return async function auth(ctx :Context, next) {
        const token = ctx.header.authorization as string;
        const user: User |undefined = await G.userMgr.getUserByToken(token);
        const isLogin = user !== undefined && !user.needRelogin();

        if(!isLogin && ctx.request.url.indexOf('/user/login') == -1) {
            ctx.body = "not login";
            return;
        }

        ctx.user = user;
        ctx.token = token;
        ctx.isLogin = isLogin;

	   // 应该改成 await next() 确保异步接口也能正常执行	
       next();
    }
}

也已设置允许跨域, 正确配置中间件

    config.cors = {
        origin: '*', // 匹配规则  域名+端口  *则为全匹配
        allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
    };

config.middleware = ['auth'];
    config.auth = {
        ignore: '*/authcallback'
    }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值