json - Angular:带有空 200/201 响应的 HttpClient 错误(始终调用 JSON.parse(""))
问题描述
在使用 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 {}
}
})
);
}
}
推荐阅读
- javascript - vuemounted()中的setInterval函数不起作用
- git - git 从 dev 分支合并到 master 直到某个提交的所有提交
- ios - 为什么在 Xcode 中有一个与我的常规项目分开的“Pods”项目?
- javascript - 如何验证跟踪代码管理器上的输入
- mysql - mysql线程卡住了锁定行的“清理”
- javascript - 如何从表单中获取实时输入并打印出来?
- django - 模拟补丁导致错误——TypeError: object() 在 python 3 中没有参数
- visual-studio - 如何在 resharper 智能感知完成期间防止输入键换行
- kubernetes - 使用 GKE Ingress 时对 readinessProbe 使用 HTTP 基本身份验证
- php - 如何在 Amazon Linux 2 CentOS7 上安装 PHP 5.56?