Cypress中使用cy.request实现接口登录失效问题排查
Cypress cy.request 登录失败问题排查与修复
核心问题原因
- 请求端点配置错误:当前代码将POST请求发送到站点根路径
/,该路径对应首页渲染路由,并未指向登录处理接口,因此后端直接返回首页HTML内容,不会执行登录逻辑。 - 请求格式不匹配:
cy.request默认将请求体序列化为JSON格式,携带Content-Type: application/json请求头;如果模拟原生HTML表单提交,后端默认按application/x-www-form-urlencoded格式解析参数,无法识别JSON格式传参,导致登录参数丢失。 - 遗漏必要校验参数:多数Web应用默认开启CSRF防护,直接发起POST请求未携带合法CSRF token时,后端会拒绝请求,不会完成登录流程。
- 登录态未同步:如果应用采用token鉴权且将token存储在
localStorage/sessionStorage中,cy.request不会自动将响应返回的token写入浏览器存储,后续cy.visit时应用无法读取登录态。 - 字段名不匹配:当前代码传参使用
passwd作为密码字段名,需和实际接口要求的字段名核对(多数后端使用password作为密码字段名)。
修复方案
方案1:调用JSON格式登录接口(和手动调通API的逻辑一致)
将请求地址替换为实际可用的登录API路径,手动同步登录态到浏览器存储:
describe('The Login By Request', () => { it('successfully logs in with request', () => { // 将url替换为之前验证可正常返回token的登录API地址,禁止使用根路径/ cy.request('POST', '/api/auth/login', { username: "johnny@email.com", password: "12345678" // 核对字段名,和接口要求保持一致 }).then((response) => { // 如果登录态存在localStorage,手动写入;cookie模式下可省略该步骤 window.localStorage.setItem('auth_token', response.body.token) }) cy.visit('/') cy.get('h1').should('contain', 'Svelte To-Do List') }) })
方案2:模拟原生HTML表单提交
添加form: true参数让cy.request自动按表单格式编码参数,同时提前获取CSRF token随请求提交:
describe('The Login By Request', () => { it('successfully logs in with form request', () => { // 先访问登录页获取CSRF token cy.visit('/login') cy.get('input[name="_csrf"]').invoke('val').then(csrfToken => { cy.request({ method: 'POST', url: '/login', // 替换为表单实际提交的action地址,不要使用/ form: true, // 开启表单格式编码 body: { username: "johnny@email.com", password: "12345678", // 核对字段名 _csrf: csrfToken // 携带CSRF校验参数 } }) }) cy.visit('/') cy.get('h1').should('contain', 'Svelte To-Do List') }) })
快速排查步骤
- 走一遍UI登录流程,打开浏览器开发者工具-网络面板,找到登录请求,核对实际请求URL、请求头Content-Type、提交的参数字段名,和
cy.request的配置逐一比对。 - 打印
cy.request的完整响应对象,确认状态码、响应头set-cookie、响应体内容是否和UI登录时的响应一致。 - 登录完成后在
cy.visit回调里打印document.cookie和window.localStorage,确认登录态是否正确写入。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

