Angular 5的Http拦截器无法检测响应头(POST)

5
我无法在拦截器中获取自定义响应头并将其记录在控制台上。已经记录了拦截器的httpResponse,请参见此处
以下是记录的响应:
HttpResponse { headers: HttpHeaders, status: 200, statusText: "OK", ok: true, … }
其中,HttpHeaders包含以下属性: lazyInit: ƒ () lazyUpdate: null normalizedNames: Map(0) {} proto: Object ok: true status: 200 statusText: "OK" type: 4
我们也在服务器端添加了“Access-control-expose-header”,但我仍然无法获取响应。不确定是否在拦截器方法中漏掉了什么。
以下是拦截器方法:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        req = req.clone({
            setHeaders: {
                'Accept': 'application/vnd.employee.tonguestun.com; version=1',
                'Content-Type': 'application/json',
            }
        });

    return next.handle(req)
        .do((ev: HttpEvent<any>) => {
            console.log(ev)
            if (ev instanceof HttpResponse) {
                console.log(ev.headers);
            }
            // return ev;
        })

}

拦截器函数

网络标签中的自定义标题

access-control-allow-credentials: true

access-control-allow-methods: GET, POST, OPTIONS

access-control-allow-origin: *

access-control-expose-headers: access-token,client,expiry,token-type,uid

access-token: haIXZmNWSdKJqN2by7JH1g

cache-control: max-age=0, private, must-revalidate

client: j_2dxD7NVMjGeX8BbBuELA

content-type: application/json; charset=utf-8

expiry: 1525931943

在网络标签中获取自定义标题

这是我的服务调用,也在调用中添加了观察“响应”。

服务调用

return this.http.post(`${environment.baseUrl}${environment.signup}`, data, {observe: "response"})
  .map(response => response);

服务调用

AppModule.ts

import { BrowserModule } from '@angular/platform-browser';
   import { NgModule } from '@angular/core';
   import { CommonModule } from '@angular/common';

   import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppInterceptor } from './services/app-interceptor.service';

import { HomeModule } from './home/home.module'; 
import { SharedModule } from './shared/shared.module';
import { AppRoutingModule } from './app-routing.module';
import { AuthService } from './services/auth.service';
import { AuthGuardService } from './services/auth-guard.service';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    CommonModule,
    HttpClientModule,
    BrowserAnimationsModule,
    HomeModule,
    SharedModule,
    AppRoutingModule,
  ],
  providers: [
    AuthService,
    AuthGuardService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AppInterceptor,
      multi: true
    },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

请帮我一下,谢谢!


1
以文本形式发布代码,而不要作为图像。 - sabithpocker
5个回答

1

我能够获取响应正文和头信息。但是头信息包含空数据。 - Sankar Namachivayam

0

我也遇到了同样的问题。如果你通过http调用你的服务,它将无法工作,因为拦截器不熟悉它,请使用httpClient,然后自动拦截器检测每个请求,并将拦截器发送的头信息发送到服务器端。

AppHttpInterceptor.ts

    import { Injectable } from "@angular/core";
    import {
        HttpInterceptor,
        HttpRequest,
        HttpResponse,
        HttpErrorResponse,
        HttpHandler,
        HttpEvent
    } from '@angular/common/http';

    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/do';
    import 'rxjs/add/operator/catch';
    import 'rxjs/add/observable/throw';
    import { Http, Response, RequestOptions, Headers } from '@angular/http';
    import { Router } from '@angular/router'


    @Injectable()
    export class AppHttpInterceptor implements HttpInterceptor {
        constructor(private router: Router){

        }
        headers = new Headers({
            'Content-Type': 'application/json',
            'Token': localStorage.getItem("Token")
        });
        intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

            console.log("intercepted request ... ");

            // Clone the request to add the new header.
            const authReq = req.clone({ headers: req.headers.set("Token", localStorage.getItem("Token")) });

            console.log("Sending request with new header now ...");

            //send the newly created request
            return next.handle(authReq)
                .catch(err => {
                    // onError
                    console.log(err);
                    if (err instanceof HttpErrorResponse) {
                        console.log(err.status);
                        console.log(err.statusText);
                        if (err.status === 401) {
                            window.location.href = "/login";
                        }
                    }
                    return Observable.throw(err);
                }) as any;
        }
    }

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { HttpClient } from "@angular/common/http";
import { FormsModule } from '@angular/forms';
import { ToasterModule, ToasterService } from "angular2-toaster";
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule,HTTP_INTERCEPTORS} from '@angular/common/http';
import {AppHttpInterceptor} from './Common/AuthInterceptor';
import { AppRoutes } from '../app/Common/Routes';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule, HttpModule,HttpClientModule, ReactiveFormsModule, FormsModule, BrowserAnimationsModule, RouterModule.forRoot(AppRoutes)
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AppHttpInterceptor,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { 
  constructor(private httpClient: HttpClient){
    this.httpClient.get("https://jsonplaceholder.typicode.com/users").subscribe(
      success => {
        console.log("Successfully Completed");
        console.log(success);
      }
    );
  }
}

我正在使用 import { HttpClient } from "@angular/common/http"; 。 在构造函数中将其命名为http。但仍未收到响应。 - Sankar Namachivayam
好的,我有一个解决方案,但需要几个小时后才能发送给你。谢谢@SankarNamachivayam - sebu
1
是的,我已经检查过了。我实际上只使用了HttpClient。问题出在服务器端。这篇文章帮助我们解决了这个问题:https://dev59.com/36fja4cB1Zd3GeqPqRY7#47539194。我们在nginx配置中漏掉了'always'关键字。感谢您的时间和努力。 - Sankar Namachivayam
欢迎 @SankarNamachivayam - sebu

0

这个Stack Overflow的回答帮助我们解决了这个问题。问题出在nginx的配置上。我们在access-control-expose-header中漏掉了always这个关键字。


0
头部映射是延迟加载的,因此您需要触发映射以加载内容,以便列出头部。
例如,调用headers.keys()或通过键headers.get('name-of-key')获取特定的头部。

您的回答可以通过提供更多支持性信息来改进。请[编辑]以添加更多细节,比如引用或文献,以便他人可以确认您的回答是否正确。您可以在帮助中心找到关于如何撰写好回答的更多信息。 - undefined

-1

来自文档 https://angular.io/guide/http#intercepting-requests-and-responses

const authReq = req.clone({
      headers: req.headers.set('Authorization', authToken)
    });

    // send cloned request with header to the next handler.
    return next.handle(authReq);

看到使用了一个新变量,看看如何通过set覆盖req.headers来更改头部。

尝试过了,但没有成功。我可以在请求中设置头信息。但是当我在克隆请求的下一个处理程序中控制台输出时,我无法获取响应头。 - Sankar Namachivayam
函数“intercept”被执行了吗?如果您想在整个请求中使用它,必须导入HTTP_INTERCEPTORS并在app.module.ts中声明。 - Eliseo
是的,它已经执行了。我在问题中更新了app.module.ts,请检查一下。 - Sankar Namachivayam
使用newreq=req.clone...并返回next.handle(newreq)。这只是一个想法,我不确定是否有效。 - Eliseo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接