我从服务器接收到一些
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。
因为它出错了:由于未设置响应类型,所以它使用默认的 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解析