使用 Fetch API 读取响应头

IT技术 javascript google-chrome-extension
2021-01-25 16:56:07

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

该扩展存储用户输入的登录数据,以前直接放入 XHR 的 open() 调用以进行 HTTP 身份验证,但在 Fetch 下不能再直接用作参数。对于 HTTP 基本身份验证,绕过此限制是微不足道的,因为您可以手动设置授权标头:

fetch(url, {
  headers: new Headers({ 'Authorization': 'Basic ' + btoa(login + ':' + pass) })
  } });

然而,HTTP Digest Auth需要更多的交互性;您需要读取服务器通过 401 响应发送给您的参数以制作有效的授权令牌。我试过WWW-Authenticate用这个片段读取响应头字段:

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

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

content-type -> text/html; charset=iso-8859-1

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

有机会使用 Fetch API 访问其他字段吗?

6个回答

当您通过 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(我们把它放在两者中)中的值。
2021-03-22 16:56:07
@sebas 看起来 Chrome(可能还有其他浏览器)对XmlHttpRequest.
2021-03-23 16:56:07
access-control-expose-headers为我工作从服务器返回的标头 - 然后标头可通过 fetch 响应 Headers 对象获得。access-control-allow-headers用于允许服务器上的请求标头(或者我会从服务器收到错误消息)
2021-03-30 16:56:07
设置Access-Control-Allow-Headers允许头部从客户端传递到服务器(例如,当If-Match)。设置Access-Control-Expose-Headers允许头部传递从服务器返回给客户端(例如,当ETag)。
2021-04-13 16:56:07
这有点愚蠢,这在 Fetch 中是不可能的,但可以通过 XmlHttpRequest 来完成。如果使用变通方法仍然可能,那么安全优势是什么?
2021-04-14 16:56:07

如果不是 CORS:

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

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

response.headers.get('x-auth-token')
response.headers.map 显示了 react native 中的所有标头,这里不确定。
2021-03-28 16:56:07

来自MDN

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

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

另外,请记住这一部分:

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

使用迭代器呈现相同的输出;只有内容类型字段。并且禁止标题名称的列表似乎仅适用于修改,并且WWW-Authenticate未列出。
2021-04-06 16:56:07

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

r.headers.forEach(function(value, name) {
    console.log(name + ": " + value);
});

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

问题:

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

如何解决:

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

response.headers.add("Access-Control-Expose-Headers","Authorization")

为什么?

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

参考:

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