Egg.js跨域问题完美解决方案:CORS配置详解

Egg.js跨域问题完美解决方案:CORS配置详解

【免费下载链接】egg 🥚 Born to build better enterprise frameworks and apps with Node.js & Koa 【免费下载链接】egg 项目地址: https://gitcode.com/gh_mirrors/egg11/egg

在前后端分离架构中,跨域资源共享(CORS,Cross-Origin Resource Sharing)是开发者绕不开的挑战。当前端应用与后端API部署在不同域名下时,浏览器的同源策略会阻止跨域请求,导致接口调用失败。作为基于Node.js和Koa的企业级框架,Egg.js提供了灵活且安全的跨域解决方案。本文将从问题分析到实际配置,带你彻底解决Egg.js应用中的跨域难题。

跨域问题原理与表现

跨域问题本质是浏览器的安全机制限制。当满足以下任一条件时,请求会被判定为跨域:

  • 协议不同(如HTTP与HTTPS)
  • 域名不同(如example.com与api.example.com)
  • 端口不同(如80端口与3000端口)

典型错误表现为控制台出现类似提示:

Access to XMLHttpRequest at 'https://api.example.com/data' from origin 'https://example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Egg.js中间件解决方案

Egg.js采用中间件机制处理HTTP请求流程,跨域问题可通过配置CORS中间件解决。框架兼容所有Koa生态的CORS中间件,推荐使用成熟的koa-cors模块。

安装依赖

npm install koa-cors --save

创建CORS中间件

在项目中创建中间件文件:

// app/middleware/cors.js
module.exports = require('koa-cors');

全局启用配置

修改配置文件启用CORS中间件:

// config/config.default.js
module.exports = {
  // 加载cors中间件
  middleware: [ 'cors' ],
  
  // cors中间件配置
  cors: {
    origin: '*', // 允许所有域名访问,生产环境建议指定具体域名
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH', // 允许的HTTP方法
    allowHeaders: 'Content-Type,Authorization', // 允许的请求头
    exposeHeaders: 'Content-Length,Date,ETag', // 允许客户端获取的响应头
    maxAge: 86400, // 预检请求缓存时间(秒)
    credentials: true, // 是否允许发送Cookie
  },
};

精细化跨域控制

实际项目中,完全开放的跨域策略可能带来安全风险。Egg.js中间件支持通过matchignore配置实现精细化控制。

路径匹配规则

// config/config.default.js
module.exports = {
  cors: {
    // 仅对/api路径启用跨域
    match: '/api',
    
    // 或者使用正则表达式匹配
    // match: /^\/api\//,
    
    // 或者使用函数自定义匹配逻辑
    // match(ctx) {
    //   return ctx.path.startsWith('/api');
    // },
    
    origin: 'https://example.com',
    credentials: true,
  },
};

多环境配置

不同环境可能需要不同的跨域策略,可通过环境配置文件区分:

// config/config.local.js (开发环境)
module.exports = {
  cors: {
    origin: '*', // 开发环境宽松策略
  },
};

// config/config.prod.js (生产环境)
module.exports = {
  cors: {
    origin: 'https://example.com', // 生产环境严格指定域名
  },
};

安全策略与CORS的协同

Egg.js内置的安全插件提供了多种防护机制,配置CORS时需注意与这些安全策略的协同工作。

CSRF防护兼容

当启用CORS并允许 credentials 时,需特别注意CSRF防护:

// config/config.default.js
module.exports = {
  security: {
    csrf: {
      // 对跨域请求忽略CSRF检查
      ignore: ctx => ctx.get('origin'),
    },
  },
};

安全域名白名单

对于需要重定向的场景,可配置安全域名白名单:

// config/config.default.js
module.exports = {
  security: {
    domainWhiteList: [ 'https://example.com' ], // 跨域重定向白名单
  },
};

常见问题解决方案

预检请求失败

若遇到OPTIONS预检请求失败,检查是否正确配置了允许的请求头和方法:

// 正确配置示例
cors: {
  allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
  allowHeaders: 'Content-Type,Authorization,X-Requested-With',
}

带Cookie的跨域请求

当需要在跨域请求中传递Cookie,需确保三方面配置:

  1. 服务端设置credentials: true
  2. 客户端请求时设置withCredentials: true
  3. origin不能设置为*,必须指定具体域名

复杂请求处理

对于包含自定义头或非简单方法的复杂请求,浏览器会先发送预检请求。可通过配置maxAge减少预检请求次数:

cors: {
  maxAge: 86400, // 预检结果缓存24小时
}

最佳实践与注意事项

生产环境配置建议

// 生产环境安全配置
cors: {
  origin: ctx => {
    const allowedOrigins = [ 'https://example.com', 'https://admin.example.com' ];
    const origin = ctx.get('origin');
    return allowedOrigins.includes(origin) ? origin : '';
  },
  credentials: true,
  allowMethods: 'GET,POST,PUT,DELETE',
  maxAge: 86400,
}

中间件顺序问题

确保CORS中间件在路由处理之前执行:

// config/config.default.js
module.exports = {
  // 中间件加载顺序,cors应放在前面
  middleware: [ 'cors', 'otherMiddleware' ],
};

调试技巧

遇到跨域问题时,可通过以下方式排查:

  1. 查看浏览器控制台的网络请求,检查预检请求和实际请求的响应头
  2. 使用Egg.js的日志功能输出CORS配置:
// app.js
module.exports = app => {
  console.log('CORS配置:', app.config.cors);
};

通过本文介绍的方法,你可以在Egg.js应用中实现安全、灵活的跨域资源共享配置。合理的CORS策略不仅能解决前后端分离架构中的通信问题,还能在安全性和开发效率之间取得平衡。实际项目中,建议根据具体的业务场景和安全要求,选择最适合的跨域解决方案。

更多关于Egg.js中间件的使用细节,可参考官方文档:docs/source/zh-cn/basics/middleware.md

安全相关配置可参考:docs/source/zh-cn/core/security.md

【免费下载链接】egg 🥚 Born to build better enterprise frameworks and apps with Node.js & Koa 【免费下载链接】egg 项目地址: https://gitcode.com/gh_mirrors/egg11/egg

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值