即使主机没有更改,赛普拉斯也会抛出 "cross origin error happened on page load"

Cypress throws "cross origin error happened on page load" even if host didn't changed

我 运行 Cypress 在 https://localhost:3000 上进行测试,这也是我的 CYPRESS_BASE_URL。导航到 / 在内部重定向到 /en,效果很好。但是我正在编写的测试是关于构建新 URL 的表单,例如 https://localhost:3000/foobar?param=value。这很有效,我什至可以看到我重定向到的页面。但是赛普拉斯抱怨这个:

Cypress detected a cross origin error happened on page load:

  > Blocked a frame with origin "https://localhost:3000" from accessing a cross-origin frame.

Before the page load, you were bound to the origin policy:

  > https://localhost:3000

A cross origin error happens when your application navigates to a new URL which does not match the origin policy above.

A new URL does not match the origin policy if the 'protocol', 'port' (if specified), and/or 'host' (unless of the same superdomain) are different.

Cypress does not allow you to navigate to a different origin URL within a single test.

You may need to restructure some of your test code to avoid this problem.

Alternatively you can also disable Chrome Web Security in Chromium-based browsers which will turn off this restriction by setting { chromeWebSecurity: false } in cypress.json.

我不想禁用 chromeWebSecurity(有效),因为我也在 运行 Firefox 上进行了此测试。我唯一能想象的就是我进行重定向的方式:window.location.href = "/foobar?param=value".

错误消息是关于更改 protocolporthost,但我正在执行其中的 none,并且我的 SSL 证书是有效的.

这可能是错误还是我忽略了什么?

这不是错误。然而,对于许多其他人来说,这是一个持续存在的问题(参见讨论 here). As per the documentation:

Cypress detected a cross-origin error happened on page load

This error means that your application navigated to a superdomain that Cypress was not bound to. Initially when you cy.visit(), Cypress changes the browser's URL to match the url passed to cy.visit(). This enables Cypress to communicate with your application to bypass all same-origin security policies among other things. When your application navigates to a superdomain outside of the current origin-policy, Cypress is unable to communicate with it, and thus fails.

If you find yourself stuck and can't work around these issues you can set chromeWebSecurity to false in your configuration file (cypress.json by default) when running in Chrome family browsers (this setting will not work in other browsers). Before doing so you should really understand and read about the reasoning here.

{"chromeWebSecurity": false}

另外,如所述here

If you attempt to visit two different superdomains, Cypress will error. Visiting subdomains works fine. You can visit different superdomains in different tests, but not in the same test.

因此,虽然您访问的是子域,但您可能需要考虑以下内容,如 documentation 中所述,用于访问不同的超级域:

it('navigates', () => {
  cy.visit('https://localhost:3000')
})

it('navigates to new origin', () => {
  cy.visit('https://localhost:3000/foobar?param=value')
})

此外,在同一文档中:

Although Cypress tries to enforce this limitation, it is possible for your application to bypass Cypress's ability to detect this.

Examples of test cases that will error due to superdomain limitations

  1. .click() an <a> with an href to a different superdomain.
  2. .submit() a <form> that causes your web server to redirect to you a different superdomain.
  3. Issue a JavaScript redirect in your application, such as window.location.href = '...', to a different superdomain.

In each of these situations, Cypress will lose the ability to automate your application and will immediately error.

因此,问题可能毕竟是 window.location.href = '...' 的使用。该文档建议查看 common workarounds.

这可能只是计划中的混乱。

TLDR - 确保所有 localhost url 使用 http:// 方案而不是 https://.

有关超级域的定义,请参阅

Yes, HTTP and HTTPS origins are different.

An origin is a combination of hostname, port, and scheme.

 http://foo.example.com:8080/
 ^^^^   ^^^^^^^^^^^^^^^ ^^^^
  ||           ||        ||
scheme      hostname    port  

所以如果我 运行 这个测试我得到 CORS 错误

it('throws a CORS error', () => {

  const domain1 = 'https://localhost:3003'
  const domain2 = 'http://localhost:3003'
  
  cy.intercept(domain1, '<html></html>').as('lh')  // stubbing because no server running

  cy.visit(domain1)

  cy.wait('@lh')

  cy.window().then(win => {
    win.location.href = domain2    // Cypress detected a cross origin error happened...
  })
})

在您的测试中,可能有几个原因

  • 通常 localhost 使用 http:// 而不是 https://。如果您尝试,浏览器会提示您 此站点无法提供安全连接。可能是赛普拉斯在看到主机名 localhost.

    时正在更正方案
  • 您的主页使用方案 http:// 但您的重定向导航到 https://.