一个 iframe 随机无法 XHR
One iframe randomly fails to XHR
我在 http://localhost:3000
上有一个页面包含一个 src
为 http://localhost:3010/login
的 iframe。 iframe 执行以下操作:
- 请求
src
html.
- 收到 302 重定向后,它会跟随它到达
http://localhost:3000/oauth/authorize?response_type=code&client_id=1&redirect_uri=http%3A%2F%2Flocalhost%3A3011%2Fauthorization_code&state={state}
。
- 然后 iframe 被重定向回它自己的来源:
http://localhost:3010/authorization_code?code={code}&state={state}
。
- 嵌入 iframe 的应用程序的服务器成功交换了访问令牌的授权代码,并重定向到
http://localhost:3010
,其中的 cookie 设置为 OAuth2 access_token
。
- 一些 JavaScript 代码将 XHR 生成为
http://localhost:3010/api/customerInfo
。
- 使用 JavaScript 在 iframe 中返回并呈现客户信息。
所以这一切都很好。
但是,当我添加第二个具有自己来源 localhost:3020
的嵌入 iframe 的应用程序时,它会经历相同的流程,其中一个应用程序的第一个 XHR 将失败并出现以下错误:
XMLHttpRequest cannot load http://localhost:3000/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3011%2Fauthorization_code&state=17nCw5o0Tr11Y6z8&client_id=1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3010' is therefore not allowed access. The response had HTTP status code 400.
这似乎有点奇怪,因为它说它无法通过 XHR 加载已经通过重定向加载的 URL。
有时一个 iframe 失败,有时另一个。每次在每个浏览器中,一个 iframe 都可以执行 XHR,而另一个 iframe 会导致此错误。我什至将两个 iframe 的初始 XHR 延迟了不同的数量,这样它们就不会重叠,但无济于事。
iframe 是动态生成的(通过 React)并具有此属性:sandbox='allow-forms allow-scripts allow-same-origin'
.
这是由于 cookie 不是端口特定的,这与将端口号视为源的一部分的同源策略不同。在这种情况下,两个 iframe 都共享 cookie,并且都使用 access_token
作为包含 OAuth 访问令牌的 cookie 的名称。完成授权过程的第二个 iframe 将覆盖第一个 iframe 的 access_token
cookie,导致来自后一个 iframe 的后续 iframe 调用失败。我通过使用唯一的 cookie 名称解决了这个问题。另一种解决方法是使用不同的主机名并编辑计算机的主机文件。
我在 http://localhost:3000
上有一个页面包含一个 src
为 http://localhost:3010/login
的 iframe。 iframe 执行以下操作:
- 请求
src
html. - 收到 302 重定向后,它会跟随它到达
http://localhost:3000/oauth/authorize?response_type=code&client_id=1&redirect_uri=http%3A%2F%2Flocalhost%3A3011%2Fauthorization_code&state={state}
。 - 然后 iframe 被重定向回它自己的来源:
http://localhost:3010/authorization_code?code={code}&state={state}
。 - 嵌入 iframe 的应用程序的服务器成功交换了访问令牌的授权代码,并重定向到
http://localhost:3010
,其中的 cookie 设置为 OAuth2access_token
。 - 一些 JavaScript 代码将 XHR 生成为
http://localhost:3010/api/customerInfo
。 - 使用 JavaScript 在 iframe 中返回并呈现客户信息。
所以这一切都很好。
但是,当我添加第二个具有自己来源 localhost:3020
的嵌入 iframe 的应用程序时,它会经历相同的流程,其中一个应用程序的第一个 XHR 将失败并出现以下错误:
XMLHttpRequest cannot load http://localhost:3000/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3011%2Fauthorization_code&state=17nCw5o0Tr11Y6z8&client_id=1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3010' is therefore not allowed access. The response had HTTP status code 400.
这似乎有点奇怪,因为它说它无法通过 XHR 加载已经通过重定向加载的 URL。
有时一个 iframe 失败,有时另一个。每次在每个浏览器中,一个 iframe 都可以执行 XHR,而另一个 iframe 会导致此错误。我什至将两个 iframe 的初始 XHR 延迟了不同的数量,这样它们就不会重叠,但无济于事。
iframe 是动态生成的(通过 React)并具有此属性:sandbox='allow-forms allow-scripts allow-same-origin'
.
这是由于 cookie 不是端口特定的,这与将端口号视为源的一部分的同源策略不同。在这种情况下,两个 iframe 都共享 cookie,并且都使用 access_token
作为包含 OAuth 访问令牌的 cookie 的名称。完成授权过程的第二个 iframe 将覆盖第一个 iframe 的 access_token
cookie,导致来自后一个 iframe 的后续 iframe 调用失败。我通过使用唯一的 cookie 名称解决了这个问题。另一种解决方法是使用不同的主机名并编辑计算机的主机文件。