使用Fetch API读取响应头

jul*_*les 44 javascript google-chrome-extension

我在Google Chrome扩展程序中拥有权限"*://*/*",我正在尝试从XMLHttpRequest切换到Fetch API.

扩展存储用户输入的登录数据,这些数据曾经直接放入XHR的HTTP Auth的open()调用中,但是在Fetch下不能再直接用作参数.对于HTTP Basic Auth,绕过此限制是微不足道的,因为您可以手动设置Authorization标头:

fetch(url, {
  headers: new Headers({ 'Authorization': 'Basic ' + btoa(login + ':' + pass) })
  } });
Run Code Online (Sandbox Code Playgroud)

然而,HTTP Digest Auth需要更多的交互性; 您需要读取服务器通过其401响应发送给您的参数以创建有效的授权令牌.我已尝试WWW-Authenticate使用此代码段阅读响应标头字段:

fetch(url).then(function(resp) {
  resp.headers.forEach(function(val, key) { console.log(key + ' -> ' + val); });
}
Run Code Online (Sandbox Code Playgroud)

但我得到的只是这个输出:

content-type -> text/html; charset=iso-8859-1
Run Code Online (Sandbox Code Playgroud)

根据Chrome的开发人员工具,这本身就是正确的,但仍然缺少大约6个字段.如果我使用resp.headers.get("WWW-Authenticate")(或任何其他字段),我只得到null.

有没有机会使用Fetch API进入其他领域?

Raj*_*nda 66

在通过CORS使用Fetch API时,存在访问响应头的限制.由于此限制,您只能访问以下标准标头:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

在为Google Chrome扩展程序编写代码时,您使用的是CORS,因此无法访问所有标头.如果您控制服务器,则可以在响应中返回自定义信息,body而不是headers

有关此限制的详细信息,请访问https://developers.google.com/web/updates/2015/03/introduction-to-fetch#response_types

  • @jules对CORS的这个限制尊重`access-control-expose-headers`-或者'access-control-allow-headers`中的值(我们把它放在两者中). (12认同)
  • `access-control-expose-headers`对我来说是服务器返回的头文件 - 然后通过fetch响应Headers对象提供头文件.并且`access-control-allow-headers`用于允许服务器上的Request头(或者我从服务器收到错误消息) (9认同)
  • 这对于Fetch来说是不可能的,但可以使用XmlHttpRequest完成.如果仍有可能采用变通方法,那么安全优势是什么? (5认同)
  • @sebas 看起来 Chrome(可能还有其他浏览器)对 `XmlHttpRequest` 施加了相同的限制。 (2认同)
  • 当允许将标头从客户端传递到服务器时(例如,“ If-Match”),请设置“ Access-Control-Allow-Headers”。当允许将标头从服务器传递回客户端时,设置“ Access-Control-Expose-Headers”(例如,“ ETag”)。 (2认同)
  • 如果您尝试使用“Access-Control-Expose-Headers”解决此问题:“*”请注意,如果请求包含身份验证,则 * 通配符不起作用。您需要通过名称调出您尝试访问的标头。 (2认同)

Nit*_*hav 47

如果不是 CORS:

Fetch 在调试或console.log响应时不显示标题

您必须使用以下方式访问标题。

response.headers.get('x-auth-token')
Run Code Online (Sandbox Code Playgroud)

  • 根据 /sf/answers/3390283991/,fetch 的 response.headers 是一个 Iterable,因此 console.log 不会以普通对象的方式显示它。 (2认同)

小智 10

为了与不支持 ES2015 迭代器(并且可能还需要 fetch/Promise polyfills)的浏览器向后兼容,Headers.forEach函数是最佳选择:

r.headers.forEach(function(value, name) {
    console.log(name + ": " + value);
});
Run Code Online (Sandbox Code Playgroud)

在 IE11 中使用 Bluebird 作为 Promise polyfill 和 whatwg-fetch 作为 fetch polyfill 进行了测试。Headers.entries()、Headers.keys() 和 Headers.values() 不起作用。


Avr*_*dor 8

来自MDN

您还可以通过访问Iterator条目来获取所有标头.

// Display the key/value pairs
for (var pair of res.headers.entries()) {
   console.log(pair[0]+ ': '+ pair[1]);
}
Run Code Online (Sandbox Code Playgroud)

另外,请记住这一部分:

出于安全原因,某些标头只能由用户代理控制.这些标头包括禁止的标头名称和禁止的响应标头名称.

  • 使用迭代器呈现相同的输出;只有内容类型字段。并且禁止标题名称的列表似乎仅适用于修改,并且“WWW-Authenticate”也未列出。 (3认同)

Oma*_*gdy 6

问题:

你可能认为这是一个前端问题。
这是一个后端问题。
浏览器不允许公开Authorization标头,除非后端告诉浏览器明确公开它。

如何解决:

这对我有用。
在后端(API)中,将其添加到响应标头中:

response.headers.add("Access-Control-Expose-Headers","Authorization")
Run Code Online (Sandbox Code Playgroud)

为什么?

安全。
防止 XSS 攻击。
这个请求应该是从后端到后端的。
后端会将 httpOnly cookie 设置到前端。
因此,您网站上的任何第三方 JS 包都不应访问授权标头。
如果您认为让前端可以访问标头是安全的,那就去做吧。
但我建议立即将服务器后端设置的 HttpOnly Cookies 发送到您的浏览器。

参考:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers


小智 5

为了解决这个限制问题,添加公开的头名称就足够了。

access-control-expose-headers: headername1, headername2, ...

设置此标头后,客户端脚本能够从响应中读取这些标头(headername1、headername2...)。