在使用AngularHttpClient
post
时,似乎默认设置是将响应视为JSON字符串。即使对于 201 响应,当响应正文为空时,这也会导致错误,因为空字符串""
JSON.parse()
失败。
解决方案是将responseType: "text"
指定为附加选项,以便空正文不被视为错误。
但是,当请求失败时,API 端点会以 JSON 格式返回错误描述(即成功时为空,错误时为 JSON(。
您如何构造HttpClient
post
以便我可以在错误消息对象失败且成功不计为错误时取回它?
例如:
.subscribe(() => {
// do something for success, no return object as the body is empty
, error => {
// do something with the returned error object
// right now success is still counted as an error due to the issue above
}
);
返回响应代码200
或201
的服务器具有空响应正文并Content-Type
指定为application/json
配置错误,因为空字符串不是有效的 JSON。
如 OP 所示,指定responseType: "text"
可以修复错误,因为空正文不会解析为 JSON。
解决方法是继续执行responseType: "text"
并检查响应正文是否为空。如果响应正文不为空,则调用JSON.parse(response)
。
例
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
type HttpOptions = {
headers?: HttpHeaders | { [header: string]: string | string[]; };
observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; };
reportProgress?: boolean; responseType?: "json" /* or "text" as "json" */;
withCredentials?: boolean;
}
let get_http_options_text = (): HttpOptions => {
return {
headers: {'Content-Type': 'text/plain'},
observe: "body",
responseType: "text" as "json", // @see https://github.com/angular/angular/issues/18586
withCredentials: true
}
}
@Injectable()
export class MyHttpService {
constructor(private http: HttpClient) {}
public post_body_as_string(url: string, body: any, http_params: HttpParams = null):
Observable<any> {
let options = get_http_options_text();
if (http_params != null) {
options['params'] = http_params;
}
return this.http.post<string>(url, body, options).pipe(
map(response => {
if (response !== '') {
return JSON.parse(response);
} else {
return {}
}
})
);
}
}