为什么这个拦截器只在Sent-Event上触发,而不是在实际响应上触发?

问题描述 投票:0回答:1

我从服务器接收到一些

multipart/mixed
内容,其中包含一些 JSON 和字节,需要将其解析为 Angular 中的对象。

这就是我发出请求的方式:

public sendRequest(headerData: string): Observable<MultipartResponse> {

    let requestHeaders: HttpHeaders = new HttpHeaders();
    requestHeaders = requestHeaders.set("X-Header-Data", headerData);
    
    return httpClient.get("localhost:12345/myroute", { headers: requestHeaders}) as Observable<MultipartResponse>;
}

我已经实现了

HttpInterceptor
来解析这样的响应:

@Injectable({ providedIn: 'root' })
export class MyInterceptor implements HttpInterceptor {

    public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        return next.handle(request).pipe(map((event: HttpEvent<any>) => {

            if (event instanceof HttpResponse)
                return response.clone({ body: new MultipartResponse(event.body); });

            return event;
        }));
    }
}

并像这样在

main.ts
中注册:

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(HttpClientModule),
    provideHttpClient(withInterceptorsFromDi()),
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MyInterceptor,
      multi: true
    }
  ],
}).catch((err) => console.error(err));

现在,当我发出请求时,拦截器会在

Sent
事件上触发一次,确认请求已成功发送,但之后就不会再触发了。相反,响应直接进入调用者,然后调用者会抛出错误,因为它尝试将整个正文解析为 JSON。

angular angular-http-interceptors
1个回答
0
投票

因为它出错了:由于未设置响应类型,所以它使用默认的 JSON 解析器,然后在尝试解析响应时出错,永远不会到达你的拦截器方法(拦截器可以使用

catchError((error: HttpErrorResponse) => {...
捕获它)。

因此,您需要禁用默认解析器。您可以添加一些标志来检查请求是否具有多部分标头数据,然后通过将响应类型更改为

text
来禁用 JSON 解析器,然后使用自定义解析器解析响应(根据需要自定义):

public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const isMixedReq = request.headers.get('X-Header-Data');

    if (isMixedReq && request.responseType === 'json') {

      request = request.clone({responseType: 'text'});

      return next.handle(request).pipe(map((response: HttpEvent<any>) => {

        if (response instanceof HttpResponse && typeof event.body === 'string')
            return response.clone({ body: new MultipartResponse(response.body) });

        return response;
      }));
  } else {
    return next.handle(request);
  }
}

方法来源:自定义JSON解析

© www.soinside.com 2019 - 2024. All rights reserved.