HttpModule和HttpClientModule的区别

用哪一个来构建一个模拟web服务来测试Angular 4应用呢?

140423 次浏览

如果你使用的是Angular 4.3,可以使用HttpClientModule中的HttpClient类。X及以上:

import { HttpClientModule } from '@angular/common/http';


@NgModule({
imports: [
BrowserModule,
HttpClientModule
],
...


class MyService() {
constructor(http: HttpClient) {...}

它是@angular/http模块的http的升级版本,有以下改进:

  • 拦截器允许将中间件逻辑插入到管道中
  • 不可变请求/响应对象
  • 请求上传和响应下载的进度事件

你可以在Angular中的拦截器和HttpClient机制的内部指南中读到它是如何工作的。

  • 类型化、同步响应体访问,包括对JSON体类型的支持
  • JSON是假定的默认值,不再需要显式解析
  • 请求后验证基于Flush的测试框架

未来旧的http客户端将被弃用。下面是提交消息官方文件的链接。

还要注意,旧的http注入使用Http类令牌,而不是新的HttpClient:

import { HttpModule } from '@angular/http';


@NgModule({
imports: [
BrowserModule,
HttpModule
],
...


class MyService() {
constructor(http: Http) {...}

另外,新的HttpClient在运行时似乎需要tslib,所以如果你使用SystemJS,你必须安装它npm i tslib并更新system.config.js:

map: {
...
'tslib': 'npm:tslib/tslib.js',

如果你使用SystemJS,你需要添加另一个映射:

'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',

我不想重复,只是以另一种方式总结(新HttpClient中添加的特性):

  • 从JSON到对象的自动转换
  • 响应类型定义
  • 事件发射
  • 简化头文件的语法
  • 拦截器

我写了一篇文章,介绍了旧的“http”和新的“HttpClient”之间的区别。我们的目标是以最简单的方式解释它。

简单介绍Angular中的新HttpClient

这是一个很好的参考,它帮助我将我的http请求切换到httpClient

文中比较了两者的不同之处,并给出了代码示例。

这只是我在项目中将服务更改为httpclient时处理的一些差异(借用了我提到的文章):

进口

import {HttpModule} from '@angular/http';
import {HttpClientModule} from '@angular/common/http';

请求和解析响应:

@angular / http

 this.http.get(url)
// Extract the data in HTTP Response (parsing)
.map((response: Response) => response.json() as GithubUser)
.subscribe((data: GithubUser) => {
// Display the result
console.log('TJ user data', data);
});

@angular /共同/ http

 this.http.get(url)
.subscribe((data: GithubUser) => {
// Data extraction from the HTTP response is already done
// Display the result
console.log('TJ user data', data);
});

你不再需要显式地提取返回的数据;默认情况下,如果你得到的数据是JSON类型,那么你不需要做任何额外的事情。

但是,如果你需要解析任何其他类型的响应,比如文本或blob,那么确保你在请求中添加了responseType。像这样:

使用responseType选项进行GET HTTP请求:

 this.http.get(url, {responseType: 'blob'})
.subscribe((data) => {
// Data extraction from the HTTP response is already done
// Display the result
console.log('TJ user data', data);
});

添加拦截器

我还使用拦截器将我的授权令牌添加到每个请求参考

像这样:

@Injectable()
export class MyFirstInterceptor implements HttpInterceptor {


constructor(private currentUserService: CurrentUserService) { }


intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {


// get the token from a service
const token: string = this.currentUserService.token;


// add it if we have one
if (token) {
req = req.clone({ headers: req.headers.set('Authorization', 'Bearer ' + token) });
}


// if this is a login-request the header is
// already set to x/www/formurl/encoded.
// so if we already have a content-type, do not
// set it, but if we don't have one, set it to
// default --> json
if (!req.headers.has('Content-Type')) {
req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
}


// setting the accept header
req = req.clone({ headers: req.headers.set('Accept', 'application/json') });
return next.handle(req);
}
}

这是一个相当不错的升级!

有一个库允许你使用带有强类型回调的HttpClient

数据和错误可以直接通过这些回调得到。

 a reason for existing

当你在可观察对象中使用HttpClient时,你必须在剩下的代码中使用.subscribe (x = >…)

这是因为Observable< __ABC0< T > >绑定到HttpResponse

这个紧密耦合代码的其余部分代替http层

这个库封装了.subscribe(x =>…)部分,只通过模型暴露数据和错误。

使用强类型回调,您只需在其余代码中处理model。

这个库被称为angular-extended-http-client

angular-extended-http-client library on GitHub

angular-extended-http-client library on NPM

非常容易使用。

示例使用

强类型的回调是

成功:

  • IObservable< T >
  • IObservableHttpResponse
  • IObservableHttpCustomResponse< T >

失败:

  • IObservableError< TError >
  • IObservableHttpError
  • IObservableHttpCustomError< TError >

在你的项目和app模块中添加包

import { HttpClientExtModule } from 'angular-extended-http-client';

和@NgModule导入

  imports: [
.
.
.
HttpClientExtModule
],

你的模型

//Normal response returned by the API.
export class RacingResponse {
result: RacingItem[];
}


//Custom exception thrown by the API.
export class APIException {
className: string;
}

你的服务

在你的服务中,你只需要用这些回调类型创建参数。

然后,将它们传递给HttpClientExt的get方法。

import { Injectable, Inject } from '@angular/core'
import { RacingResponse, APIException } from '../models/models'
import { HttpClientExt, IObservable, IObservableError, ResponseType, ErrorType } from 'angular-extended-http-client';
.
.


@Injectable()
export class RacingService {


//Inject HttpClientExt component.
constructor(private client: HttpClientExt, @Inject(APP_CONFIG) private config: AppConfig) {


}


//Declare params of type IObservable<T> and IObservableError<TError>.
//These are the success and failure callbacks.
//The success callback will return the response objects returned by the underlying HttpClient call.
//The failure callback will return the error objects returned by the underlying HttpClient call.
getRaceInfo(success: IObservable<RacingResponse>, failure?: IObservableError<APIException>) {
let url = this.config.apiEndpoint;


this.client.get(url, ResponseType.IObservable, success, ErrorType.IObservableError, failure);
}
}

您的组件

在你的组件中,你的服务被注入并调用getRaceInfo API,如下所示。

  ngOnInit() {
this.service.getRaceInfo(response => this.result = response.result,
error => this.errorMsg = error.className);


}

回调中返回的响应错误都是强类型的。如。响应是类型RacingResponse,而错误是类型APIException

您只能在这些强类型回调中处理model。

因此,其余的代码只知道模型。

此外,你仍然可以使用传统的路径,从服务API返回Observable<HttpResponse<T>>。

HttpClient是4.3附带的一个新API,它更新了API,支持进度事件,默认的json反序列化,拦截器和许多其他伟大的特性。在这里查看更多< em > < a href = " https://angular。Io /guide/http" rel="nofollow noreferrer">https://angular.io/guide/http

Http是较旧的API,最终将被弃用。

由于它们在基本任务中的用法非常相似,我建议使用HttpClient,因为它是更现代、更容易使用的替代方案。