问题症状
在浏览器的控制台窗口中,我看到以下之一:
- 加载失败......没有"访问控制允许来源"页首
- 跨来源请求已阻止:相同来源政策不允许读取远程资源......原因:CORS 页首"访问控制-允许-来源"缺失
- 加载失败......对预检查请求的响应未通过访问控制检查:请求的资源上不存在"访问控制-允许-来源"页首。来源......因此不允许访问
消息中经常提及的一个关键字是 Access-Control-Allow-Origin
。
条件
一个基于浏览器的网络应用程序可能是一个 应用框架应用 ,正在尝试进行跨域调用,以便从外部网络服务获取共享资源。这称为 CORS 请求(跨来源资源共享)。
有一个 基于浏览器的 CORS 标准 可以管理此类跨来源的调用。当不满足某些条件时,会发生上述错误。
解决方案
这未必是缺陷,因为它可能涉及一个用户的 Web 应用程序和远程外部服务刻意不允许的用例。
当一个来源(www.orgin1.com)呼叫另一个来源(www.arigin2.com)时,这称为跨来源请求。要使此请求生效,必须满足某些条件。被调用的外部服务(www.arigin2.com)需要返回 HTTP 标头 Access-Control-Allow-Origin
在其回复中。
如果外部服务未返回此标头,则浏览器对 CORS 规格的遵循停止请求,并返回上述错误中的一个。
提这些问题
- 调用的起点 URL(或来源)是什么?有时这在错误消息本身中。
- 调用的外部服务 URL 是什么?有时会在控制台的错误消息中。
- 正在检索什么,为什么?它是 PNG 文件吗?脚本、CSS 或字体文件?检索的具体内容是什么,用于什么?这有助于了解用例以及为什么这个远程位置的资产很重要。
-
此外部资源需要身份验证才能获取吗?如果需要重定向,则
Access-Control-Allow-Origin
响应标头可能无法返回,调用将会失败。直接将资源的 URL 复制到新的 无痕 浏览器标签页中。这可以很好地测试它在一般情况下是否可访问,但不能保证它可以在网络应用的代码中工作。
- 您可以在浏览器的"网络"标签中看到 选项 HTTP 方法调用吗?当跨域请求中存在自定义请求标头、身份验证或其它条件时,浏览器会进行额外的 HTTP 调用。这也称为预检查电话。网络应用的代码没有明确地完成。后台的浏览器可创建并使其成为 CORS 规格标准的一部分。
当进行此 选项调用时,此调用的响应中需要某些值,以使其成功,以及要使资源进行实际的 HTTP 调用。如果 Options 调用失败,则不会取回资源,并且浏览器的控制台中会显示 CORS 错误。
如果您看到 Options 电话,请记下。此外,如果您在 Options 电话之前看到一个重定向(状态 302)电话,请记下。
如果 Options 通话发生重定向,那么 Options 通话很可能会失败。这意味着获取资源的调用也将失败,并触发 CORS 错误。
- 获取外部资源的用例是什么?首先要了解为什么要检索此外部资源。这对于提出解决方法或所需的更改可能很重要。
- 生成一个 H AR 文件。获得通话失败以及之前和之后发生的情况的快照可能有助于调试问题,并使用户无需重复通话。可以检查请求和响应中的页首,以及识别 选项通话和重定向。
可能的后续步骤
-
谁拥有外部服务器?也许服务器可进行修改,以遵循 CORS 规格标准,以返回
Access-Control-Allow-Origin
页首。然而,即使服务器是内部控制的,这也不是万能的。某个外部服务不想共享资源可能有充分的原因。
如果外部服务器不是内部控制的,那么可以与该供应商合作,或提出另一个解决方法,假定用例被认为是有效的。
- 该应用是否使用 Zendesk App Framework编写?后台代理服务器可通过 client.request() 调用。通过设置使用此代理 CORS:false 在client.request的设置中。请注意"false" 也是设置的默认值。由于代理服务是一项后台服务,它无需遵循基于浏览器的 CORS 规格,因此跨域调用可能会使用代理成功。
这也并非总是能解决所有问题。代理服务不支持从外部服务检索二值文件或二值信息。这也可能还有其他特定于应用的原因。
- 资源是否可以直接嵌入到网络应用中?请考虑将其包含在网络应用中,而不是跨来源获取资源。这样就完全避免了跨来源调用(因为它现在是本地资源)以及任何可能消失的 CORS 问题。然而,这并非总是可以解决。有时外部资源 URL 不会事先知道,或者资源太大,无法作为本地资源,或者资源更改过于频繁,无法作为本地静态资源下载。
- 浏览器版本是什么?尽管 CORS 规格是一种标准,浏览器返回的错误消息可能会不同。Chrome 返回与 Firefox 不同的控制台消息。
- 有时没有解决方法。有时来自外部服务的资源请求不应该在浏览器网络应用的背景信息中共享。资源负责人可决定其是否共享资源。这不取决于网络应用。这可能是预期的。
如需更多信息,请查阅这些资源:
- 来自 Widget 的文章:跨来源资源共享
- 来自 Web.Dv 的文章:跨来源资源共享(CORS)
- 来自 Firefox 的文章:跨来源资源共享(CORS)
- 来自 Firefox 的文章:选项
- 来自 抓取的文章:抓取
- 来自 抓取的文章:CORS 协议
翻译免责声明:本文章使用自动翻译软件翻译,以便您了解基本内容。 我们已采取合理措施提供准确翻译,但不保证翻译准确性
如对翻译准确性有任何疑问,请以文章的英语版本为准。