HttpModule 和 HttpClientModule 的区别

Difference between HttpModule and HttpClientModule

使用哪个构建模拟 Web 服务来测试 Angular 4 应用程序?

如果您使用 Angular 4.3.x 及更高版本,请使用 HttpClientModule 中的 HttpClient class:

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

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

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

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

  • Interceptors allow middleware logic to be inserted into the pipeline
  • Immutable request/response objects
  • Progress events for both request upload and response download

您可以在 Insider’s guide into interceptors and HttpClient mechanics in Angular 中了解它的工作原理。

  • Typed, synchronous response body access, including support for JSON body types
  • JSON is an assumed default and no longer needs to be explicitly parsed
  • Post-request verification & flush based testing framework

今后将弃用旧的 http 客户端。以下是 commit message and the official docs.

的链接

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

注入的
import { HttpModule } from '@angular/http';

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

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

此外,新的 HttpClient 似乎在运行时需要 tslib,因此如果您使用 [=24],则必须安装它 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 自动转换为 object
  • 响应类型定义
  • 事件触发
  • headers
  • 的简化语法
  • 拦截器

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

Simply about new HttpClient in Angular

这是一个很好的 reference,它帮助我将 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/common/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);
      });

添加拦截器

我还使用拦截器为每个请求添加了我的授权令牌,reference

像这样:

@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

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

当您将 HttpClient 与 Observable 一起使用时,您必须在其余代码中使用 .subscribe(x=>...)

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

http 层 其余代码 紧密结合

该库封装了 .subscribe(x => ...) 部分,并仅通过您的模型公开数据和错误。

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

库名为 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>

将包添加到您的项目和应用程序模块中

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);

  }

回调中的responseerror return 都是强类型的。例如。 response 是类型 RacingResponse 并且 errorAPIException.

您只在这些强类型回调中处理您的模型。

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

此外,您仍然可以使用传统路由和 return Observable<HttpResponse<T>> 来自服务 API.

HttpClient 是 4.3 附带的新 API,它更新了 API,支持进度事件,json默认反序列化、拦截器和许多其他很棒的功能。在这里查看更多 https://angular.io/guide/http

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

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