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
相关产品推荐
相关产品推荐

