XMLHttpRequest的getResponseHeader()有哪些限制?

30

我注意到当正常进行请求时,XMLHttpRequest.getResponseHeader()的结果并不总是与实际返回的头部匹配。

例如,假设我正在进行对https://foo.example.com/api/resource/100xhr请求。在Chrome开发者工具的“网络”选项卡下,我可以看到响应已被发送,我也可以看到所有的响应头(比如说有10个)。然而,执行以下代码却得到了不同的结果:

> response
  XMLHttpRequest
> response.getAllResponseHeaders();
  "content-type: text/html
  " 

有什么限制可以使用哪些HTTP头部?这与响应类型有关吗?我记得在处理404时会获得完整的头部,但在处理400时只有这个。

怎么回事?


如果我在这个页面上向http://stackoverflow.com/发出请求,我可以获得所有的头信息。我不确定如何重现这个问题。 - pimvdb
我意识到这个问题比较模糊,正在努力缩小范围以找到合适的解决方案。原始请求是跨域请求,需要使用Access-Control-Allow-Origin。抱歉问题表述可能有些仓促,稍后会详细说明:目前我还没有时间进一步调查此事。我希望这是某种我不知道的已知限制。 - maligree
2个回答

37
目前对于XMLHttpRequest API的标准化仅限制了对Set-CookieSet-Cookie2头字段的访问:

client.getAllResponseHeaders()

返回响应中除了那些字段名为Set-CookieSet-Cookie2的所有头。

任何其他头字段都应该被返回。
但是,由于你正在进行跨域请求,因此浏览器需要实现XMLHttpRequest Level 2,因为原始的XMLHttpRequest仅允许同源请求:

XMLHttpRequest Level 2规范增强了XMLHttpRequest对象的新功能,例如跨域请求[...]

在此,您可以读到“跨源资源共享规范过滤了对于非同源请求公开的getResponseHeader()头。 ”。该规范禁止访问除简单响应头字段(即Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma)之外的任何响应头字段:

用户代理必须过滤掉除那些是简单响应头之外的所有响应头[…]。

例如,XMLHttpRequest的getResponseHeader()方法因此不会公开任何未在上述列表中指定的标头。


1
好的,谢谢。不过还有一些谜团没有解开...我已经设置了适当的 Access-Control-Expose-Headers: -- 只发现它只在 Gecko 中有效,而在 WebKit 中无效。WebKit 愉快地“拒绝获取不安全的头文件(..)”,而 Gecko 则看不到问题。第二个问题:getAllResponseHeaders() 是错误的。我可以使用 getResponseHeader() 获取前者未列出为可用的标头。 - maligree
@maligree: WebKit目前尚未支持Access-Control-Expose-Headers,那么其他浏览器又如何呢? - Gumbo
是的,我遇到了那个bugzilla问题--但看到它被打开的日期,我对它持保留态度。至于第二个问题,在Firefox 6中我看到getAllResponseHeaders()返回"",而getResponseHeader('content-length')getResponseHeader('www-authenticate')(其中一个我设置并且Access-Control-Expose-Header)返回正确的头部值。我现在不想暴露使用的URI,但如果有帮助的话,我可以稍后设计一个隔离的测试用例。 - maligree
@maligree 你是不是想说 null? 参考 https://bugzilla.mozilla.org/show_bug.cgi?id=608735 - Knu

3

这里涉及到 Access-Control-Allow-Origin 头部,它可以防止某些头部信息暴露给浏览器。详见 Mozilla 开发者文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接