Chrome中缺少Http Response标头,但是Postman会显示它们

时间:2017-06-12 14:07:42

标签: rest angular

在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:“”,状态:200,ok:true,statusText:“OK”,标题:   标题...}标题:Headers_headers:Map(0)_normalizedNames:   地图(0) proto :Objectok:truestatus:200statusText:“OK”类型:2url:   “http://localhost:8080/backend/rest/login”_ body:“” proto :正文

但是当我向邮递员发送相同的帖子请求时,我得到了预期的结果:

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中的标题?

更新 我也在使用CORSFilter,它允许Javascript首先联系我的后端。这是我在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>

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

3 个答案:

答案 0 :(得分:13)

默认情况下,CORS响应仅公开这6个标题:

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

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

  

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>

答案 1 :(得分:0)

我使用以下解决方案在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

答案 2 :(得分:0)

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

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