5月27日 23:17

Cypress 如何处理跨域问题?

答案

Cypress 处理跨域问题有两种主要方式:

  1. 禁用 Chrome Web 安全:在 cypress.config.js 中设置 chromeWebSecurity: false,允许跨域导航和访问跨域 iframe。这是最简单的方式,但仅适用于 Chromium 内核浏览器。

  2. 使用 cy.origin() 命令:从 Cypress 9.6.0 起,可通过 cy.origin() 在不同域上执行操作,Cypress 会为新源创建 iframe 并通过 postMessage 通信。这是官方推荐的跨域测试方案。

javascript
// 方式一:禁用 Chrome Web 安全 // cypress.config.js module.exports = { e2e: { chromeWebSecurity: false } }; // 方式二:cy.origin() cy.origin("https://example.com", () => { cy.visit("/login"); cy.get("input[name=email]").type("test@example.com"); cy.get("button[type=submit]").click(); });

追问:chromeWebSecurity: false 有什么局限?

  • 仅对 Chromium 内核浏览器有效,Firefox 等浏览器不支持此选项
  • 不会绕过 cy.visit() 的超域限制,即不能在同一个测试中 cy.visit() 不同超域的 URL
  • 生产环境不存在此开关,测试可能掩盖真实的跨域问题

追问:cy.origin() 的注意事项?

  • 回调函数内无法直接引用外部作用域的变量,需通过第二个参数传入:
javascript
const username = "test@example.com"; cy.origin("https://example.com", { args: { username } }, ({ username }) => { cy.get("input[name=email]").type(username); });
  • 回调内不能使用 cy.session()、自定义命令等部分 API
  • 每次调用 cy.origin() 会创建新的 iframe 上下文,有性能开销

追问:还有其他方案吗?

可通过服务器端反向代理(如 nginx)将不同域的 API 映射到同源路径下,从根本上消除跨域。这种方式不依赖 Cypress 配置,但需要额外的基础设施支持。

nginx
# nginx 反向代理示例 location /external-api/ { proxy_pass https://api.example.com/; }
标签:Cypress