【问题标题】:Read response headers from API response - Angular 5 + TypeScript从 API 响应读取响应标头 - Angular 5 + TypeScript
【发布时间】:2018-06-19 10:15:54
【问题描述】:

我正在触发一个HTTP 请求,并且我得到了有效的响应。该响应还有一个我希望阅读的标题X-Token。我正在尝试下面的代码来读取标题,但是,结果我得到了 null

this.currentlyExecuting.request = this.http.request(reqParams.type, reqParams.url, {
    body: reqParams.body,
    responseType: 'json',
    observe: 'response'
}).subscribe(
    (_response: any) => {
        // Also tried _response.headers.init();
        const header = _response.headers.get('X-Token');
        console.log(header);
        onComplete(_response.body);
     },
    _error => {
        onComplete({
            code: -1,
            message: Constants.WEBSERVICE_INTERNET_NOT_CONNNECTED
        });
    }
);

API 的响应在 Chrome 检查中检查时显示标头存在。

【问题讨论】:

  • 您是否从服务器端公开了 x-token?使用“访问控制公开标头”。因为不是所有的头部都允许从客户端访问,你需要从服务器端公开它们。
  • 如果他在控制台中有它,那么是的,他暴露了它。
  • @HrishikeshKale:你是对的。 Access-Control-Expose-Headers 工作。您可以将此作为答案发布。
  • 我已将此作为答案发布。快乐编码:)
  • 毛毛虫,我不同意。我有一种情况,我在服务器上添加标头并且可以在浏览器控制台中看到它,但浏览器代码看不到它。由于 CORS,我必须明确将其标记为(在我的服务器代码中)暴露给浏览器。

标签: angular http typescript angular5


【解决方案1】:

您是否使用access-control-expose-headers 从服务器端公开了X-Token?因为不是所有的头部都允许从客户端访问,你需要从服务器端公开它们

同样在您的前端,您可以使用新的HTTP 模块来获得使用{observe: 'response'} 的完整响应

http
  .get<any>('url', {observe: 'response'})
  .subscribe(resp => {
    console.log(resp.headers.get('X-Token'));
  });

【讨论】:

  • post 方法是否也一样...我收到错误消息“在预检响应中 Access-Control-Allow-Headers 不允许请求标头字段观察。”
  • 在哪里可以了解更多信息?这解决了我的问题,但我想知道发生了什么
  • @KaiCriticallyAcclaimedCooper 是的,这里肯定是链接html5rocks.com/en/tutorials/cors,还有 Github 问题github.com/angular/angular/issues/6583
  • 我仍然有阅读标题的问题,我找到了答案,看到这个:stackoverflow.com/questions/58601675/…
  • 我可以在邮递员中看到标题。这是否意味着标题已暴露?当我使用上面的代码@HrishikeshKale 时,我没有得到那个标题
【解决方案2】:

在我的POST 响应中,我想要authorization header,因为我有JWT Token。 所以我从this 帖子中读到的是我想要的标题应该从后端添加为Expose Header。 所以我所做的就是将Authorization 标头添加到我的Exposed Header 中,就像在我的filter class 中一样。

response.addHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader("Access-Control-Allow-Headers", "Authorization, X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept, X-Custom-header");
response.addHeader(HEADER_STRING, TOKEN_PREFIX + token); // HEADER_STRING == Authorization

在我的角度方面

在组件中。

this.authenticationService.login(this.f.email.value, this.f.password.value)
  .pipe(first())
  .subscribe(
    (data: HttpResponse<any>) => {
      console.log(data.headers.get('authorization'));
    },
    error => {
      this.loading = false;
    });

在我的服务端。

return this.http.post<any>(Constants.BASE_URL + 'login', {username: username, password: password},
  {observe: 'response' as 'body'})
  .pipe(map(user => {
       return user;
  }));

【讨论】:

    【解决方案3】:

    您应该使用新的HttpClientYou can find more information here

    http
      .get<any>('url', {observe: 'response'})
      .subscribe(resp => {
        console.log(resp.headers.get('X-Token'));
      });
    

    【讨论】:

      【解决方案4】:

      正如 Hrishikesh Kale 所解释的,我们需要传递 Access-Control-Expose-Headers。

      我们如何在 WebAPI/MVC 环境中做到这一点:

      protected void Application_BeginRequest()
              {
                  if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
                  {
                      //These headers are handling the "pre-flight" OPTIONS call sent by the browser
                      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
                      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
                      HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "TestHeaderToExpose");
                      HttpContext.Current.Response.End();
                  }
              }
      

      另一种方法是我们可以在 webApiconfig.cs 文件中添加如下代码。

      config.EnableCors(new EnableCorsAttribute("", headers: "", methods: "*",exposedHeaders: "TestHeaderToExpose") { SupportsCredentials = true });
      

      **我们可以在 web.config 文件中添加自定义标头,如下所示。 *

      <httpProtocol>
         <customHeaders>
            <add name="Access-Control-Expose-Headers" value="TestHeaderToExpose" />
         </customHeaders>
      </httpProtocol>
      

      我们可以创建一个属性并使用该属性来装饰方法。

      编码愉快!!

      【讨论】:

        【解决方案5】:

        您可以通过这种方式(Angular 6)从发布响应标头中获取数据:

        import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
        
        const httpOptions = {
          headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
          observe: 'response' as 'response'
        };
        
        this.http.post(link,body,httpOptions).subscribe((res: HttpResponse<any>) => {
          console.log(res.headers.get('token-key-name'));
        })
        

        【讨论】:

          【解决方案6】:

          您可以使用以下代码获取标题

          let main_headers = {}
          this.http.post(url,
            {email: this.username, password: this.password},
            {'headers' : new HttpHeaders ({'Content-Type' : 'application/json'}), 'responseType': 'text', observe:'response'})
            .subscribe(response => {
              const keys = response.headers.keys();
              let headers = keys.map(key => {
                `${key}: ${response.headers.get(key)}`
                  main_headers[key] = response.headers.get(key)
                 }
                );
            });
          

          稍后我们可以从 json 对象中获取所需的标头。

          header_list['X-Token']
          

          【讨论】:

            【解决方案7】:

            角度 7 服务:

            this.http.post(environment.urlRest + '/my-operation',body, { headers: headers, observe: 'response'}); 组件:
                this.myService.myfunction().subscribe(
                      (res: HttpResponse) => {
                          console.log(res.headers.get('x-token'));
                            } ,
                    错误 =>{
                    })
                

            【讨论】:

              【解决方案8】:

              试试这个简单的代码。

              1.组件端代码: 获取 body 和 header 属性。这里在正文中有一个标记,在标题中有Authorization

              loginUser() {
                  this.userService.loginTest(this.loginCred).
                  subscribe(res => {
                      let output1 = res;
                      console.log(output1.body.token);
                      console.log(output1.headers.get('Authorization'));
                  })
              }
              

              2。服务端代码: 在正文中发送登录数据,并观察Observable 中任何组件端订阅的响应。

              loginTest(loginCred: LoginParams): Observable<any> {
                  const header1= {'Content-Type':'application/json',};
                  const body =  JSON.stringify(loginCred);
                  return this.http.post<any>(this.baseURL+'signin',body,{
                      headers: header1,
                      observe: 'response',
                      responseType: 'json'
                  });
              }
              

              【讨论】:

                【解决方案9】:

                当从 ASP.NET Core 服务获取标头时,我必须执行以下操作才能让标头出现在 SPA Angular 应用程序中:

                var builder = WebApplication.CreateBuilder(args);
                
                services.AddCors(options =>
                {
                    options.AddPolicy("MyExposeResponseHeadersPolicy",
                        builder =>
                        {
                            builder.WithOrigins("https://*.example.com")
                                   .WithExposedHeaders("x-custom-header");
                        });
                });
                
                builder.Services.AddControllers();
                
                var app = builder.Build();
                

                【讨论】:

                  猜你喜欢
                  • 2016-09-02
                  • 2020-05-26
                  • 1970-01-01
                  • 2018-07-31
                  • 2017-09-06
                  • 2018-06-15
                  • 2019-03-04
                  • 1970-01-01
                  • 2011-08-25
                  相关资源
                  最近更新 更多