Angular 5:HttpClient的基本用法

时间:2023-01-21 17:48:31

Angular 4.3引入了新的用于http请求的接口HttpClient。它旨在替换之前版本的接口Http。有以下新特性:

  1. 对响应的body做类型检查
  2. 默认返回的是JSON对象,不再需要使用json()显式解析返回的数据
  3. 支持拦截器
  4. 支持进度事件
  5. 请求后验证和基于刷新的测试框架

安装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();
// 发次第二次请求