Angular的HttpClient深入分析
HttpClient执行http请求。该服务作为可注入类提供,带有执行 HTTP 请求的方法。每个请求方法都有多个签名,并且返回类型会根据所调用的签名(主要的值是 observe
和 responseType
)而有所不同。
方法
/**构建HttpRequest参数**/
new HttpRequest(
method: string,
url: string,
body?:any, //相当于post参数
third?: T |
{ headers?: HttpHeaders;
reportProgress?: boolean;
params?: HttpParams;
responseType?: "arraybuffer" | "blob" | "text" | "json";
withCredentials?: boolean;
},
fourth?:
{ headers?: HttpHeaders;
reportProgress?: boolean;
params?: HttpParams;
responseType?: "arraybuffer" | "blob" | "text" | "json";
withCredentials?: boolean;
}
);
/**HttpClient.request的参数**/
request(
first: string | HttpRequest<any>,
url?: string,
options: {
body?: any;
headers?: HttpHeaders | { [header: string]: string | string[]; };
observe?: HttpObserve;
params?: HttpParams | { [param: string]: string | string[]; };
reportProgress?: boolean;
responseType?: "arraybuffer" | ... 2 more ... | "json"; withCredentials?: boolean;
} = {}): Observable<any> //返回值
/**HttpClient.get的参数**/
get(
url: string,
options: {
headers?: HttpHeaders | { [header: string]: string | string[]; };
observe?: HttpObserve;
params?: HttpParams | { [param: string]: string | string[]; };
reportProgress?: boolean;
responseType?: "arraybuffer" | "blob" | "text" | "json"; withCredentials?: boolean;
} = {}): Observable<any>
/**HttpClient.delete的参数**/
delete(
url: string,
options: {
headers?: HttpHeaders | { [header: string]: string | string[]; };
observe?: HttpObserve;
params?: HttpParams | { [param: string]: string | string[]; };
reportProgress?: boolean;
responseType?: "arraybuffer" | "blob" | "text" | "json"; withCredentials?: boolean;
} = {}): Observable<any>
/**HttpClient.post的参数**/
post(
url: string,
body: any,
options: {
headers?: HttpHeaders | { [header: string]: string | string[]; };
observe?: HttpObserve;
params?: HttpParams | { [param: string]: string | string[]; };
reportProgress?: boolean;
responseType?: "arraybuffer" | "blob" | "text" | "json";
withCredentials?: boolean;
} = {}): Observable<any>
/**HttpClient.get的参数**/
put(
url: string,
body: any,
options: {
headers?: HttpHeaders | { [header: string]: string | string[]; };
observe?: HttpObserve;
params?: HttpParams | { [param: string]: string | string[]; };
reportProgress?: boolean;
responseType?: "arraybuffer" | "blob" | "text" | "json"; withCredentials?: boolean;
} = {}): Observable<any>
//请求超时
this.http.get('http://api.geonames.org/postalCodeSearchJSON',
{search:params})
.retryWhen(error => error.delay(500))
.timeout(2000,new Error('delay exceeded')) // <- 超时
.map(res => res.json()。postalCodes);
参数说明
header
选项可用于设置请求头信息,可以帮助控制请求或处理响应数据的方式。
以下是 HttpClient 的 headers 选项示例说明:
Content-Type
设置请求体的 MIME 类型,用于说明请求体的数据格式,例如 JSON 格式。
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
this.http.post(URL, body, httpOptions).subscribe(data => {
console.log(data);
});
Accept
设置响应体允许的 MIME 类型,用于告知服务器请求方能够处理的数据格式。
const httpOptions = {
headers: new HttpHeaders({ 'Accept': 'application/json' })
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
Authorization
设置请求头的 token 或 JWT 字符串,用于验证身份。
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QifQ.O7lCStt09iW7Yz3MV9biEZZ6OkmiEnkGGTJw0d2mKpM';
const httpOptions = {
headers: new HttpHeaders({ 'Authorization': `Bearer ${token}` })
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
Cache-Control
设置请求或响应的缓存控制策略。
const httpOptions = {
headers: new HttpHeaders({ 'Cache-Control': 'no-cache' })
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
除以上常见的请求头信息外,您也可以自行设置其他的请求头字段。需要注意的是,某些请求头字段可能需要特定的权限或设置才能正常工作。
context
HttpClient 的 context 选项实际上是 HttpClient 的扩展选项。可以用于传递从应用程序的各个部分收集到的上下文信息,这些信息可以帮助识别请求的来源或跟踪请求的执行情况。
以下是 HttpClient 的 context 选项示例说明:
context
此选项允许您在应用程序的许多部分之间传递多个上下文值。为此,您可以定义输入类型为 HttpContext
的对象。例如:
import { HttpClient, HttpContext } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor(private http: HttpClient) {}
sendRequest(url: string) {
const context = new HttpContext().set(PERFORMANCE_MARK, 'foo');
const options = { context }; // 将上下文传递给HttpClient的options选项
return this.http.get(url, options);
}
}
ngContextToken
ngContextToken是一个特定于 Angular 的上下文令牌,可以传递给 HttpClient 的 context 选项以定义与 Angular 环境相关的信息。
import { HttpClient, ngContextToken } from '@angular/common/http';
import { ErrorHandler, Injectable, NgZone } from '@angular/core';
@Injectable()
export class MyErrorHandler implements ErrorHandler {
constructor(private zone: NgZone, private http: HttpClient) {}
handleError(error: any): void {
const context = { info: error.message, zone: this.zone };
const options = { context: new Map([[ngContextToken, context]]) };
this.http.post('/api/error', { error }, options)
.subscribe(() => { }, error => console.error(error));
}
}
以上是 HttpClient 的 context 选项的示例说明,只要您定义 HttpClient 的 扩展选项 对象,添加您需要传递的上下文信息,就可以很容易地使用这个特性。
observe
选项有三个值:
- 'body': 仅请求响应体部分
通过传递该参数,您将只获得 Http 响应数据的主体部分。此选项适用于处理不需要或不关心进度情况的情形。
const httpOptions = { observe: 'body' };
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data); // 只获得响应体
});
- 'response': 整个请求响应
通过传递该参数,您将获得完整的 Http 响应数据,包括状态码、头部信息和响应主体。此选项适用于需要完整数据或处理请求进度的情形。
const httpOptions = { observe: 'response' };
this.http.get(URL, httpOptions).subscribe((response) => {
console.log(response.status); // 显示状态码
console.log(response.headers); // 显示头部信息
console.log(response.body); // 显示响应主体
})
- 'events': 获得请求进度事件流
通过传递该参数,您将获得一个带有 Http 请求进度事件的 Observable 对象。此选项适用于需要监视请求进度的情形。
const httpOptions = { observe: 'events' };
this.http.get(URL, httpOptions).subscribe((event) => {
if (event.type == HttpEventType.DownloadProgress) {
console.log(`Received download progress: ${event.loaded} bytes of ${event.total}`)
} else if (event.type == HttpEventType.Response) {
console.log('Received full response: ', event.body)
}
})
请注意,这些选项可以与 responseType 选项结合使用,以设置响应数据的类型。例如,将 'responseType' 设置为 'blob' 可以让您从响应中获取二进制数据。
params
HttpClient 的 params 选项用于设置查询字符串参数,可用于向 API 发送有关资源请求所需的参数。这些参数将作为 HTTP 请求的一部分传递,并在服务器端解析和使用。
以下是 HttpClient 的 params 选项示例说明:
- 传递简单字符串参数
可以通过设置 params 选项来传递简单的查询字符串参数。例如,以下请求将在 URL 上添加名为 'q' 的查询参数。
const httpOptions = {
params: { q: 'search' }
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
- 传递多个参数
可以通过传递一个对象来设置多个查询字符串参数。这些参数将作为名称和值的键值对发送到服务器端。
const httpOptions = {
params: {
id: '123',
name: 'John',
email: 'john@example.com'
}
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
- 处理复杂查询参数
可以通过两种方式来处理复杂的查询字符串参数:
- 使用编码的查询字符串参数值,这样可以避免特殊字符引起的问题。
- 将参数值设置为数组或对象,以支持嵌套查询字符串参数。
例如,以下请求将发送包含嵌套字段和数组值的查询字符串:
const httpOptions = {
params: {
filter: {
ages: [20, 30, 40],
names: ['John', 'Mary']
}
}
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
- 自定义参数编码
HttpClient 的 params 选项支持自定义参数编码,以便提供更精细的控制,例如限制字符集或提供某些编码格式。要使用自定义编码器,只需设置对象的 params
为 HttpHeaders 参数,并添加自定义编码器。
const httpOptions = {
params: new HttpHeaders()
.set('filter', 'age > 18')
.set('format', 'json')
.set('charset', 'utf-8')
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
以上是 HttpClient 的 params 选项的示例说明,如果您还需要具体了解其他方面的信息,请参阅 Angular 的官方文档。
reportProgress
HttpClient 的 reportProgress 选项用于在 HTTP 请求和响应过程中通知进度变化。通过将该选项设置为 true,您可以通过 HttpEvent
的事件流来获得包含进度信息的事件统计。
以下是 HttpClient 的 reportProgress 选项示例说明:
- 提供上传进度
如果要在文件上传期间通知进度,则可以将 reportProgress 设置为 true,并在进度事件中使用 loaded 和 total 事件。例如:
uploadFile(file: File) {
const formData = new FormData();
formData.append('file', file, file.name);
const httpOptions = {
reportProgress: true
};
const req = new HttpRequest(
'POST',
'/api/upload',
formData,
httpOptions
);
this.http.request(req).subscribe(event => {
if (event.type === HttpEventType.UploadProgress) {
const percentDone = Math.round((100 * event.loaded) / event.total);
console.log(`File is ${percentDone}% uploaded`);
} else if (event.type === HttpEventType.Response) {
console.log(`Server response: ${event.body}`);
}
});
}
- 提供下载进度
如果要在文件下载期间通知进度,则可以将 reportProgress 设置为 true,并使用 loaded 和 total 事件警报。例如:
downloadFile() {
const httpOptions = {
responseType: 'blob',
reportProgress: true
};
this.http.get('/api/download', httpOptions).subscribe(event => {
if (event.type === HttpEventType.DownloadProgress) {
const percentDone = Math.round((100 * event.loaded) / event.total);
console.log(`File is ${percentDone}% downloaded`);
} else if (event.type === HttpEventType.Response) {
const blob = new Blob([event.body], {type: 'application/octet-stream'});
saveAs(blob, 'file.zip');
}
});
}
- 提供通用进度
除了下载和上传进度之外,您还可以使用 reportProgress 选项来跟踪 HTTP 请求和响应过程的通用进度。这有助于您诊断慢速或错误的响应。例如:
fetchData() {
const httpOptions = {
reportProgress: true
};
this.http.get('/api/data', httpOptions).subscribe(event => {
if (event.type === HttpEventType.Sent) {
console.log('Request is sent');
} else if (event.type === HttpEventType.ResponseHeader) {
console.log('Received response header');
} else if (event.type === HttpEventType.DownloadProgress) {
console.log(`Downloaded ${event.loaded} of ${event.total} bytes`);
} else if (event.type === HttpEventType.Response) {
console.log('Received full response', event.body);
}
});
}
以上是 HttpClient 的 reportProgress 选项的示例说明,如果您还需要具体了解其他方面的信息,请参阅 Angular 的官方文档。
reponseType
HttpClient的 responseType 选项用于设置 HTTP 响应的预期响应数据类型。可以使用 responseType 选项指示 HttpClient 解析响应时预期的格式,并将响应的主体转换为合适的 JavaScript 类型。
以下是 HttpClient 的 responseType 选项示例说明:
- 文本响应类型
可以使用 responseType: 'text'
来接收文本类型的响应主体数据。
const httpOptions = {
responseType: 'text'
};
this.http.get<string>(URL, httpOptions).subscribe(data => {
console.log(data);
});
- JSON 响应类型
可以使用 responseType: 'json'
来接收 JSON 格式的响应主体数据,该响应将被解析为 JavaScript 对象或数组。
const httpOptions = {
responseType: 'json'
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
- ArrayBuffer 和 Blob 类型
可以使用 responseType 选项设置为 'arraybuffer' 和 'blob',以指定响应主体的类型。这可以用于处理二进制数据的响应,例如图片或音频文件等。
const httpOptions = {
responseType: 'blob'
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
- 重写响应类型解析
如果默认的响应类型无法满足您的需求,可以通过传递responseType: 'json'
的参数来自定义响应解析逻辑。
this.http.get(URL, { responseType: 'text' }).pipe(
map((data: string) => {
try {
return JSON.parse(data);
} catch (error) {
return null;
}
})
).subscribe(data => {
console.log(data);
});
以上是 HttpClient 的 responseType 选项的示例说明,如果您还需要具体了解其他方面的信息,请参阅 Angular 的官方文档。
withCredentials
HttpClient 的 withCredentials 选项用于控制是否在跨域请求中发送和接收 cookie。默认情况下,如果跨域请求未指定 withCredentials,则浏览器不会将 cookie 发送到服务器或接收响应中的 cookie。
以下是 HttpClient 的 withCredentials 选项示例说明:
- 设置为 true
当将 withCredentials 设置为 true 时,浏览器将处理跨域请求,并在请求和响应中将 cookie 发送到服务器和接收响应中的 cookie。
const httpOptions = {
withCredentials: true
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
- 请求未包含 withCredentials
当请求未包含 withCredentials,则浏览器不会在请求中包括 cookie,因此也无法在响应中接收 cookie。
this.http.get(URL).subscribe(data => {
console.log(data);
});
- 跨域资源共享 (CORS)
在跨域请求中使用 withCredentials 时,请确保服务器支持 CORS,在使用此选项发送 cookie 时,可能会出现跨域问题。
- 支持跨站点资源共享 (CORS)
可以在设置 CORS HEADERS 的情况下启用跨站点资源共享。在服务器响应的 HEADER 中设置 'Access-Control-Allow-Credentials: true',以允许跨站点请求接收和发送 cookie。
accessControlHeader {
'Access-Control-Allow-Origin': 'http://localhost:4200',
'Access-Control-Allow-Credentials': 'true'
};
const httpOptions = {
withCredentials: true,
headers: new HttpHeaders(accessControlHeader)
};
this.http.get(URL, httpOptions).subscribe(data => {
console.log(data);
});
以上是 HttpClient 的 withCredentials 选项的示例说明,如果您还需要具体了解其他方面的信息,请参阅 Angular 的官方文档。
转载自:https://juejin.cn/post/7240006787948183610