HttpModule和HttpClientModule之间的区别


229

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



1
我昨天实际上在我的博客上写了它的一些新功能:blog.jonrshar.pe/2017/Jul/15/angular-http-client.html
jonrsharpe


6
本教程使用HttpModule和angular.io/guide/http使用HttpClientModule,并且都没有解释何时应使用一个或另一个,或者需要使用哪个版本的Angular。
米奇·西格尔

检查此角8 HttpClient的实施例消耗基于REST API freakyjolly.com/...
代码间谍

Answers:


338

如果您使用的是Angular 4.3.x及更高版本,请使用以下HttpClientHttpClientModule

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

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

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

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

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

您可以在Insider的Angular拦截器和HttpClient机制指南中了解其工作原理。

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

继续使用旧的HTTP客户端。这是提交消息官方文档的链接。

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

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

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

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

另外,HttpClient似乎tslib在运行时需要新的,因此如果您使用的是npm i tslibsystem.config.js则必须安装并更新SystemJS

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

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

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

1
我正在尝试导入HttpClientModule。但是在使用“ npm start”命令安装的node_modules目录中不存在“ @ angular / common / http”。你能帮我吗?
Dheeraj Kumar

1
@DheerajKumar,您使用的是哪个版本?它仅在4.3.0及更高版本中可用
Max Koretskyi

我从git下载了角度快速入门。在package.json中,出现“ @ angular / common”:“ ^ 4.3.0”。但没有@ angular / common / http。
Dheeraj Kumar

删除node_modules文件夹并npm install再次运行
Max Koretskyi

5
我遇到了同样的问题(我正在使用System.js)。此答案缺少的一件事是,您还需要按如下所示映射system.js中的新模块: '@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
Tyler O

43

不想重复,而只是以其他方式进行总结(新HttpClient中添加的功能):

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

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

简单介绍一下Angular中的新HttpClient


18

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

https://blog.hackages.io/angular-http-httpclient-same-but-different-86a50bbcc450

它比较了两者之间的差异,并提供了代码示例。

这只是我在项目中将服务更改为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);
      });

添加拦截器

我还使用拦截器为每个请求添加授权令牌:

这是一个很好的参考:https : //offering.solutions/blog/articles/2017/07/19/angular-2-new-http-interface-with-interceptors/

像这样:

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

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


你需要在你的答案的相关信息,而不是仅仅作为一个链接
迈克尔

1

有一个库允许您将HttpClient与强类型的回调一起使用

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

存在的原因

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

这是因为可观察< HttpResponse< T>>绑定到HttpResponse对象

这将http层其余代码紧密结合在一起。

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

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

该库称为angular-extended-http-client

GitHub上的angular-extended-http-client库

NPM上的angular-extended-http-client库

很好用。

样本用法

强类型的回调是

成功:

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

  }

这两个,响应错误的回调返回的是强类型。例如。响应RacingResponse类型,错误APIException

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

因此,其余代码仅了解您的模型。

同样,您仍然可以使用传统路由,并从Service API 返回Observable < HttpResponse<T >>。


0

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

Http是较旧的API,最终将不推荐使用。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.