javascript 使用获取API阅读响应标头

osh3o9ms  于 2023-01-19  发布在  Java
关注(0)|答案(9)|浏览(279)

我在一个具有"*://*/*"权限的Google Chrome扩展中,我正在尝试从XMLHttpRequest切换到Fetch API
这个扩展存储用户输入的登录数据,这些数据过去直接放在XHR的open()调用中用于HTTP Auth,但是在Fetch下不能再直接用作参数。对于HTTP Basic Auth,绕过这个限制是微不足道的,因为你可以手动设置一个Authorization头:

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

然而HTTP摘要认证需要更多的交互性;您需要读取服务器随其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
有没有可能使用API访问其他字段?

klh5stk1

klh5stk11#

在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

3zwtqj6y

3zwtqj6y2#

如果不是CORS:

**在调试时或如果您console.log**响应,则获取不显示标头。

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

response.headers.get('x-auth-token')
1qczuiv0

1qczuiv03#

MDN开始
您还可以通过访问条目Iterator来获取所有的头。

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

此外,请记住this部件:
出于安全原因,某些标头只能由用户代理控制。这些标头包括禁止的标头名称和禁止的响应标头名称。

fkaflof6

fkaflof64#

问题:

您可能认为这是前端问题。
这是一个后端问题。
浏览器不允许公开Authorization标头,除非Backend通知浏览器显式公开它。

如何解决:

这对我很有效。
在后端(API),将以下内容添加到响应头:

    • x一a0一b1 x**

为什么?

安全。
以防止XSS漏洞。
这个请求应该是从后端到后端的。
后端将为前端设置httpOnly cookie。
因此授权头不应该被任何第三方JS包在您的网站上访问。
如果你认为通过前端访问头部是安全的,那么就这样做吧。
但我建议您立即将服务器后端设置的HttpOnly Cookie添加到浏览器中。

参考:

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

iovurdzv

iovurdzv5#

为了向后兼容不支持ES 2015迭代器的浏览器(可能还需要fetch/Promise多边形填充),最好选择Headers.forEach函数:

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

在IE11中测试,将Bluebird用作Promise polyfill,将whatwg-fetch用作提取polyfill。标题.条目()、标题.键()和标题.值()不起作用。

nsc4cvqm

nsc4cvqm6#

为了解决这个限制问题,添加公开的头文件名就足够了。
访问控制暴露报头:标头名称1、标头名称2、...
在设置这个头之后,客户端脚本能够从响应中读取这些头(headername1、headername2 ...)。

9rbhqvlz

9rbhqvlz7#

为了响应跨源请求,请将'Access-Control-Expose-Headers': '*'添加到响应标头中,以便所有标头都可在客户端代码中读取。还可以通过指定标头名称而不是通配符来指示要公开的标头。
请注意,如果您访问的URL具有“凭据”,则通配符per MDN“*"将被视为文字。

e7arh2l6

e7arh2l68#

我将编译我的解决方案,这是所有从上面:
对于get标头,请用途:

response.headers.get('ex-token')

为了使其工作,我们必须在后端API上设置exposeHeader('ex-token')'
有了Java Spring就变成这样了:

configuration.addExposedHeader("ex-token");
du7egjpx

du7egjpx9#

如果您在Program.cs文件或Startup.cs中使用.net(取决于.net版本),则必须执行以下操作:

builder.Services.AddCors(options =>
{
    options.AddPolicy(MyAllowSpecificOrigins,
    builder =>
    {
        builder
            .SetIsOriginAllowed(p => true)
            .WithOrigins("http://localhost:3000", "http://*:3000")
            .AllowCredentials()
            .WithExposedHeaders("X-Pagination") /*custom header*/
            .AllowAnyHeader()
            .AllowAnyMethod();
    });
});

}

相关问题