是否可以捕获 CORS 错误?

2022-01-15 00:00:00 cors javascript html

这个问题与跨域资源共享(CORS,http://www.w3.org/TR/cors/).

This question is related to Cross-Origin Resource Sharing (CORS, http://www.w3.org/TR/cors/).

如果在发出 CORS 请求时出现错误,Chrome(以及 AFAIK 其他浏览器)会将错误记录到错误控制台.示例消息可能如下所示:

If there is an error when making a CORS request, Chrome (and AFAIK other browsers as well) logs an error to the error console. An example message may look like this:

XMLHttpRequest 无法加载 http://domain2.example.Access-Control-Allow-Origin 不允许来源 http://domain1.example.

XMLHttpRequest cannot load http://domain2.example. Origin http://domain1.example is not allowed by Access-Control-Allow-Origin.

我想知道是否有办法以编程方式获取此错误消息?我尝试将我的 xhr.send() 调用包装在 try/catch 中,我还尝试添加一个 onerror() 事件处理程序.两者都没有收到错误消息.

I'm wondering if there's a way to programmatically get this error message? I've tried wrapping my xhr.send() call in try/catch, I've also tried adding an onerror() event handler. Neither of which receives the error message.

推荐答案

参见:

  • http://www.w3.org/TR/cors/#handling-a-response-to-a-cross-origin-request

...以及 XHR Level 2 中关于 CORS 的注释:

...as well as notes in XHR Level 2 about CORS:

  • http://www.w3.org/TR/XMLHttpRequest2/

有意过滤信息.

几个月后这里的后续评论询问为什么";第一个链接中的锚点缺少一些字符,这使得很难看到我指的是文档的哪一部分.

Edit many months later: A followup comment here asked for "why"; the anchor in the first link was missing a few characters which made it hard to see what part of the document I was referring to.

这是一个安全问题 - 试图避免在 HTTP 标头中暴露可能敏感的信息.关于 CORS 的 W3C 链接说:

It's a security thing - an attempt to avoid exposing information in HTTP headers which might be sensitive. The W3C link about CORS says:

用户代理必须过滤掉所有响应头,除了那些是简单响应头或字段名称与 Access-Control-Expose-Headers 头的值之一匹配的不区分大小写的 ASCII 头(如果any),在将响应标头暴露给 CORS API 规范中定义的 API 之前.

User agents must filter out all response headers other than those that are a simple response header or of which the field name is an ASCII case-insensitive match for one of the values of the Access-Control-Expose-Headers headers (if any), before exposing response headers to APIs defined in CORS API specifications.

该段落包含简单响应标头"的链接,其中列出了 Cache-Control、Content-Language、Content-Type、Expires、Last-Modified 和 Pragma.所以那些都通过了.Access-Control-Expose-Headers 标头"部分允许远程服务器通过在其中列出其他标头来公开其他标头.有关详细信息,请参阅 W3C 文档.

That passage includes links for "simple response header", which lists Cache-Control, Content-Language, Content-Type, Expires, Last-Modified and Pragma. So those get passed. The "Access-Control-Expose-Headers headers" part lets the remote server expose other headers too by listing them in there. See the W3C documentation for more information.

请记住,您有一个来源 - 假设是您在浏览器中加载的网页,运行一些 JavaScript - 脚本正在向另一个来源发出请求,这通常是不允许的,因为恶意软件可以做到讨厌的事情就是这样.因此,运行脚本并代表其执行 HTTP 请求的浏览器充当了看门人.

Remember you have one origin - let's say that's the web page you've loaded in your browser, running some bit of JavaScript - and the script is making a request to another origin, which isn't ordinarily allowed because malware can do nasty things that way. So, the browser, running the script and performing the HTTP requests on its behalf, acts as gatekeeper.

浏览器查看来自其他来源"服务器的响应,如果它似乎没有参与"CORS - 所需的标头丢失或格式错误 - 那么我们处于否决的位置相信.我们无法确定在本地运行的脚本是否善意行事,因为它似乎正在尝试联系不希望以这种方式联系的服务器.浏览器当然不应该通过仅将其整个响应传递给脚本而不进行过滤来泄漏"来自该远程服务器的任何敏感信息 - 这基本上是允许跨域请求.会出现信息泄露漏洞.

The browser looks at the response from that "other origin" server and, if it doesn't seem to be "taking part" in CORS - the required headers are missing or malformed - then we're in a position of no trust. We can't be sure that the script running locally is acting in good faith, since it seems to be trying to contact servers that aren't expecting to be contacted in this way. The browser certainly shouldn't "leak" any sensitive information from that remote server by just passing its entire response to the script without filtering - that would basically be allowing a cross-origin request, of sorts. An information disclosure vulnerability would arise.

这可能会使调试变得困难,但这是安全性与可用性的权衡,因为用户"在此上下文中是开发人员,因此安全性被赋予了重要的优先级.

This can make debugging difficult, but it's a security vs usability tradeoff where, since the "user" is a developer in this context, security is given significant priority.

相关文章