You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cypress.IO JSONP支持问题:无法通过cy.wait等待JSONP请求响应

解决Cypress中JSONP请求cy.wait()超时的问题

这个问题我之前也碰到过!主要原因是JSONP请求和XHR的机制完全不一样——JSONP是通过动态插入<script>标签来发起请求的,根本不属于XHR范畴,所以你之前用的cy.server()和cy.route()(包括新版的cy.intercept默认配置)都不会捕获这类请求,自然会超时。下面给你几个可行的解决方案:

方案1:监听JSONP的全局回调函数(最直接)

大多数JSONP请求都会指定一个全局回调函数,请求完成后会执行这个函数来返回数据。我们可以通过cy.stub或cy.spy监听这个回调的调用,以此判断请求是否完成。

示例代码:

假设你的应用中JSONP的回调函数叫jsonpHandler,测试代码可以这么写:

// 先获取window对象,给回调函数打桩并命名别名
cy.window().then(win => {
  cy.stub(win, 'jsonpHandler').as('jsonpCallback')
})

// 触发发起JSONP请求的UI事件
cy.get('#trigger-jsonp-btn').click()

// 等待回调函数被调用,替代原来的cy.wait('@bar')
cy.wait('@jsonpCallback')

// 还可以断言回调收到的数据是否符合预期
cy.get('@jsonpCallback').should('have.been.calledWith', {
  // 这里写你预期返回的数据结构
})

如果你的应用使用动态生成的回调名(很多JSONP会自动生成随机回调名,比如callback=jsonp_12345),可以结合cy.intercept先提取回调名,再监听:

cy.intercept('GET', '**/foo?callback=*', (req) => {
  // 从请求参数里拿到动态生成的回调名
  const callbackName = req.query.callback
  // 在window上给这个回调函数打桩
  cy.window().then(win => {
    cy.spy(win, callbackName).as('dynamicJsonpCallback')
  })
})

// 触发UI事件
cy.get('#trigger-btn').click()

// 等待动态回调被调用
cy.wait('@dynamicJsonpCallback')

方案2:等待JSONP对应的<script>标签加载完成

JSONP请求会在DOM中插入一个<script>标签,我们可以通过等待这个标签出现并加载完成来判断请求状态:

// 触发发起JSONP请求的UI事件
cy.get('#trigger-btn').click()

// 等待对应src的script标签出现(表示请求已发起)
// 再结合should('exist')确保标签加载完成
cy.get('script[src*="/foo?callback="]').should('exist')

注意事项

  • 旧版本的cy.server()和cy.route()完全不支持JSONP,建议升级到Cypress 6+版本,使用cy.intercept来处理这类场景,功能更灵活。
  • 如果JSONP请求的回调函数是局部的(不是全局挂载在window上),可能需要调整应用代码,或者用方案2来处理。

内容的提问来源于stack exchange,提问作者Luis Somoza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:47:59