Angular 4.3引入了新的用于http请求的接口HttpClient。它旨在替换之前版本的接口Http。有以下新特性:
- 对响应的body做类型检查
- 默认返回的是JSON对象,不再需要使用json()显式解析返回的数据
- 支持拦截器
- 支持进度事件
- 请求后验证和基于刷新的测试框架
安装HttpClientModule
HttpClient属于@angular/common/http包的模块HttpClientModule。使用HttpClient需要导入HttpClientModule。
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {HttpClientModule} from '@angular/common/http';
@NgModule({
imports: [
BrowserModule,
//在BrowserModule之后导入HttpClientModule
HttpClientModule,
],
})
export class AppModule {}
请求JSON数据
使用get请求/api/items的JSON数据。
JSON格式:
{
"results": [
"Item 1",
"Item 2",
]
}
示例组件
@Component(...)
export class MyComponent implements OnInit {
results: string[];
// 注入HttpClient
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.http.get('/api/items').subscribe(data => {
//此处不需要使用data.json()来解析响应数据
this.results = data['results'];
});
}
}
由于HttpClient默认使用JSON格式,所以在处理响应数据不再需要显式解析JSON。
类型检查
在上面的例子里没有直接使用data.results获取data的results属性的值,而是使用下标语法data["results"]。这是由于http响应不知道data的数据结构。
如果需要对返回的数据做类型检查,可是使用泛型对get请求指定响应数据类型。
interface ItemsResponse {
results: string[];
}
例子里的get请求改为
http.get<ItemsResponse>('/api/items').subscribe(data => {
this.results = data.results;
});
获取完整的response
上面的例子获取的是返回的JSON数据,如果需要获取整个respons,包括响应头信息等,可以对get函数指定
http
.get<MyJsonData>('/data.json', {observe: 'response'})
.subscribe(resp => {
console.log(resp);
console.log(resp.headers.get('X-Custom-Header'));
console.log(resp.body.someField);
});
response.body就是上面例子里的data,也是一个JSON对象。
错误处理
http请求失败会返回一个HttpErrorResponse:
http
.get<ItemsResponse>('/api/items')
.subscribe(
data => {...},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
console.log('An error occurred:', err.error.message);
} else {
console.log(err);
console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
}
}
);
我们也可以使用rxjs的retry()重试来处理错误:
import 'rxjs/add/operator/retry';
...
http
.get<ItemsResponse>('/api/items')
// 最大重试次数设定为3
.retry(3)
//
.subscribe(...);
请求非JSON数据
HttpClient返回的数据默认为JSON对象。可以使用是非JSON对象:
http
.get('/textfile.txt', {responseType: 'text'})
// 返回的数据类型为string
.subscribe(data => console.log(data));
Post请求
post请求和get类似,同样有subscribe函数,body默认为json对象:
const body = {name: 'Brad'};
http
.post('/api/developers/add', body)
.subscribe(...);
添加请求头信息
可以使用headers设置请求头信息:
http
.post('/api/items/add', body, {
headers: new HttpHeaders().set('Authorization', 'my-auth-token'),
})
.subscribe();
添加Url参数
使用params给Url添加参数:
http
.post('/api/items/add', body, {
params: new HttpParams().set('id', '3'),
})
.subscribe();
注意
需要注意的是,所有HttpClient返回的Observable都为冷对象。返回Observable并不意味者发起了请求,只有对用subscrib函数时才会真正发起http请求。对Observable调用多次subscribe函数,就会发起多次请求。
const req = http.post('/api/items/add', body);
// 此时没有发起请求
req.subscribe();
// 发次第一次请求
req.subscribe();
// 发次第二次请求