【问题标题】:Http Response headers missing in chrome, but with Postman they show upchrome 中缺少 Http 响应标头,但使用 Postman 时它们会出现
【发布时间】:2021-09-21 15:23:56
【问题描述】:

在 Angular 中调用我的 REST 服务时,没有响应标头。

Angular 中的登录方法

login(username: string, password: string) {
    const credentials = { "username": username, "password": password };
    return this.http.post(this.url, credentials)
      .subscribe(
        data => console.log(data), // JSON.stringify(data.headers) also is empty
        error => console.log(error)
      );
  }

Chrome 开发工具控制台中的输出

响应 {_body: "", status: 200, ok: true, statusText: "OK", headers: 标头...}标头:标头_标头:映射(0)_normalizedNames: Map(0)proto: Objectok: truestatus: 200statusText: "OK"type: 2url: "http://localhost:8080/backend/rest/login"_body: ""原型:正文

但是当我用 postman 发送相同的 post 请求时,我得到了预期的结果:

Access-Control-Allow-Credentials →true
Access-Control-Allow-Origin →chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Authorization →Bearer eyJ[...]
Connection →keep-alive
Content-Length →0
Date →Mon, 12 Jun 2017 13:19:54 GMT
Server →WildFly/10
Vary →Origin
X-Powered-By →Undertow/1

REST 服务

@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response authenticateUser(CredentialsDTO credentialsDTO) {
    try {
        authService.login(credentialsDTO.getUsername(), credentialsDTO.getPassword());
    } catch (WrongCredentialsException e) {

        return Response.status(Status.FORBIDDEN).entity("WrongCredentialsException").build();
    } 

    // Issue token
    String token = issueToken(credentialsDTO.getUsername());

    // Return the token on the response
    return Response.ok().header(AUTHORIZATION, "Bearer " + token).build();
}

为什么我在 chrome 中看不到标题?

更新 我还使用了一个允许 Javascript 首先联系我的后端的 CORSFilter。这就是它在我的 web.xml 中的配置方式

<filter>
    <filter-name>CORS</filter-name>
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>

    <init-param>
        <param-name>cors.allowGenericHttpRequests</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowOrigin</param-name>
        <param-value>*</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowSubdomains</param-name>
        <param-value>false</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportedMethods</param-name>
        <param-value>GET, HEAD, POST, DELETE, OPTIONS</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportedHeaders</param-name>
        <param-value>*</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>cors.maxAge</param-name>
        <param-value>3600</param-value>
    </init-param>

</filter>

<filter-mapping>
    <!-- CORS Filter mapping -->
    <filter-name>CORS</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

虽然我认为它被配置为允许一切,但我不确定这是否与我的问题有关。

【问题讨论】:

  • data 是一个响应对象,你应该执行 console.log(data.headers) 来查看它们,或者如果你看不到它们,可以在日志中 JSON.stringify 它们。
  • @SrAxi 没有。 @Tim 你的服务器没有发送 Access-Control-Expose-Headers 设置为 Authorization 所以它对 js 不可用。
  • @SrAxi 如果被禁止,则根本不会有任何响应。
  • @n00dl3 你不会得到“拒绝访问”响应吗?不过,你是对的。
  • @Tim: &lt;init-param&gt;&lt;param-name&gt;cors.exposedHeaders&lt;/param-name&gt;&lt;param-value&gt;Authorization&lt;/param-value&gt;&lt;init-param&gt;

标签: rest angular


【解决方案1】:

默认情况下,CORS 响应仅向脚本公开这 6 个标头:

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

为了允许脚本访问服务器发送的其他头,服务器需要发送Access-Control-Expose-Headers Header。

Access-Control-Expose-Headers 响应标头通过列出其名称来指示哪些标头可以作为响应的一部分公开给脚本。

例如:Access-Control-Expose-Headers: Authorization, X-Foobar

您可以调整您的 web.xml 文件,包括此文件,以允许从生成 XHR 的脚本访问 Authorization 标头:

<init-param>
  <param-name>cors.exposedHeaders</param-name>
  <par‌​am-value>Authorizati‌​on</param-value>
<ini‌​t-param>

【讨论】:

    【解决方案2】:

    我使用以下解决方案在 Owin 自托管 web api 中允许我的自定义标头

    using Owin;
    using Microsoft.Owin.Cors;
    using System.Threading.Tasks;
    using System.Web.Cors;
    
    namespace App.Web.App_Start
    {
        public static class CorsConfig
        {
            public static void Configure(IAppBuilder app)
            {
                var allowedOrigins = "comma,separated,list,of,origins";
                var corsPolicy = new CorsPolicy
                {
                    AllowAnyHeader = true,
                    AllowAnyMethod = true,
                    AllowAnyOrigin = false,
                    SupportsCredentials = true
                };
    
                corsPolicy.ExposedHeaders.Add("Custom-Header");
    
                foreach (string origin in allowedOrigins.Split(','))
                    corsPolicy.Origins.Add(origin);
    
                app.UseCors(new CorsOptions
                {
                    PolicyProvider = new CorsPolicyProvider
                    {
                        PolicyResolver = context => Task.FromResult(corsPolicy)
                    }
                });
            }
    
        }
    
    }
    

    我调用这样的方法 CorsConfig.Configure(app); // 应用是 Owin.IAppBuilder

    【讨论】:

      【解决方案3】:

      HttpResponse 对象中的标头是延迟加载的,因此在您强制加载值之前,headers 将显示为空。尝试调用response.headers.keys() 以查看所有可用的标头名称。顺便说一句,这也会强制将所有值加载到映射response.headers.headers

      如果您只需要访问一个特定的标头值,请务必使用headers.get('my-header-name')

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-07
        • 1970-01-01
        • 2016-05-09
        • 1970-01-01
        • 2018-04-25
        相关资源
        最近更新 更多