HttpClient can't parse empty response

末鹿安然 提交于 2019-11-27 06:12:53

问题


I have an interceptor that adds a token in the headers. However, if I use it after a POST request my Observer in the subscription is not triggered.

Interceptor:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.authService = this.inj.get(AuthService);
if (!this.authService.isLoggedIn()) {
  return next.handle(req);
}

const changedReq = req.clone({headers: req.headers.set('Authorization', `Bearer ${this.authService.getToken()}`)});
return next.handle(changedReq);
}

Service:

saveBeer(beerForm: BeerForm): Observable<Response> {
let body = JSON.stringify(beerForm);
let headers = new HttpHeaders({
  'Content-Type': 'application/json'
});

return this.http.post(this.apiUrl, body, {headers: headers});
}

Component:

onSubmitCreateBeer(): void {
this.beerService.saveBeer(this.beerForm)
  .takeUntil(this.ngUnsubscribe)
  .subscribe(
    (response: Response) => {
      // On response
      this.router.navigate(['/beers']);
    }, error => {
      // On error
    }, () => {
      // On complete
    });
}

My problem is that on response is never triggered so my navigation step doesn't work. If I disable the interceptor everything works.

Any ideas?


回答1:


I got it working. The issue was that my observer was expecting json in the response. However, after i get 200 OK the response contains nothing in the body. That is an error, so the error function was called.

Solution 1 is to set responseType: text.

saveBeer(beerForm: BeerForm): Observable<any> {
let body = JSON.stringify(beerForm);
let headers = new HttpHeaders({
  'Content-Type': 'application/json'
});

return this.http.post(this.apiUrl, body, {headers: headers, responseType: 'text'});
}

Solution 2 is to return 204 from the backend.

Both work fine for now. There is a bug report about that:

https://github.com/angular/angular/issues/18680




回答2:


My workaround is an HttpInterceptor that catches errors when the status code is 200 and returns an HttpResponse with a null body instead (just like HttpClient does with 204 Not Content responses):

@Injectable()
export class EmptyResponseBodyErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
  .catch((err: HttpErrorResponse) => {
    if (err.status == 200) {
      const res = new HttpResponse({
        body: null,
        headers: err.headers,
        status: err.status,
        statusText: err.statusText,
        url: err.url
      });
      return Observable.of(res);
    } else {
      return Observable.throw(err);
    }
  });
 }
}


来源:https://stackoverflow.com/questions/47207264/httpclient-cant-parse-empty-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!