Cypress E2E测试出现重复Cookie设置异常,求根因与解决办法
根因分析
- Nginx Cookie配置不统一:服务器返回的
Set-Cookie头中,Domain属性存在两种格式——env.app.domain.com和.env.app.domain.com,导致Cypress将其识别为两组独立的Cookie。原生浏览器可能会自动兼容这类差异,但Cypress对Cookie的Domain解析更严格,因此出现重复存储的情况。 - Cypress与原生浏览器的Cookie处理差异:Cypress的Cookie管理机制对
hostOnly属性的判断更敏感,当同名Cookie的Domain格式不同时,会分别存储。后续请求可能错误携带hostOnly: false的xsrftoken,导致认证失败。 - cy.session的缓存特性限制:
cy.session会缓存sessiontoken这类稳定的认证Cookie,但xsrftoken通常是一次性生成的,缓存的sessiontoken无法与新生成的xsrftoken匹配,进而导致会话失效。
规避方案
1. 修正Nginx的Set-Cookie配置
统一Cookie的Domain属性,消除格式差异:
- 若需匹配所有子域名,设置
Domain=.env.app.domain.com(带前置点) - 若仅当前域名有效,直接移除
Domain属性,让浏览器自动设置hostOnly: true
示例Nginx配置片段:
location / { add_header Set-Cookie "xsrftoken=xxx; Path=/; Domain=.env.app.domain.com; HttpOnly; Secure"; add_header Set-Cookie "sessiontoken=xxx; Path=/; Domain=.env.app.domain.com; HttpOnly; Secure"; }
2. 在Cypress中拦截修正Cookie
使用cy.intercept拦截响应,修改Set-Cookie头统一Domain格式:
cy.intercept('POST', '/login', (req) => { req.continue((res) => { const correctedCookies = res.headers['set-cookie']?.map(cookie => { return cookie.replace(/Domain=env\.app\.domain\.com/, 'Domain=.env.app.domain.com') }) if (correctedCookies) res.headers['set-cookie'] = correctedCookies }) })
3. 清理重复Cookie
在cy.session的验证阶段或登录前,主动清理不符合要求的Cookie:
cy.session('login', () => { cy.visit('/login') // 执行登录操作 cy.get('#username').type('test') cy.get('#password').type('123456') cy.get('#submit').click() }, { validate: () => { cy.getCookies().then(cookies => { // 清理hostOnly为false的目标Cookie const invalidCookies = cookies.filter(c => !c.hostOnly && (c.name === 'xsrftoken' || c.name === 'sessiontoken') ) invalidCookies.forEach(c => cy.clearCookie(c.name, { domain: c.domain })) }) } })
4. 优化单测试用例的Cookie清理
封装自定义命令,避免重复编写清理逻辑:
// cypress/support/commands.js Cypress.Commands.add('prepareLogin', () => { cy.clearAllCookies() cy.visit('/login') }) // 测试用例中调用 it('登录后访问首页', () => { cy.prepareLogin() // 执行登录操作 cy.get('#username').type('test') cy.get('#password').type('123456') cy.get('#submit').click() cy.url().should('include', '/dashboard') })
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

