Angular4 Angular HttpClient

标签: HttpClient
43人阅读 评论(0) 收藏 举报
分类:

安装

首先,我们需要更新所有的包到 4.3.0-rc.0 版本。然后,我们需要在 AppModule 中导入 HttpClientModule 模块。具体如下:

import { HttpClientModule } from '@angular/common/http';
@NgModule({
 declarations: [
   AppComponent
 ],
 imports: [
   BrowserModule,
   HttpClientModule
 ],
 bootstrap: [AppComponent]
})
export class AppModule { }

现在一切准备就绪。让我们来体验一下我们一直期待的三个新特性。

特性一 默认 JSON 解析

现在 JSON 是默认的数据格式,我们不需要再进行显式的解析。即我们不需要再使用以下代码:

http.get(url).map(res => res.json()).subscribe(...)

现在我们可以这样写:

http.get(url).subscribe(...)

特性二 支持拦截器 (Interceptors)

拦截器允许我们将中间件逻辑插入管线中。

请求拦截器 (Request Interceptor)

import {
  HttpRequest,
  HttpHandler,
  HttpEvent
} from '@angular/common/http';

@Injectable()
class JWTInterceptor implements HttpInterceptor {
  
  constructor(private userService: UserService) {}
  
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const JWT = `Bearer ${this.userService.getToken()}`;
    req = req.clone({
      setHeaders: {
        Authorization: JWT
      }
    });
    return next.handle(req);
  }
}

如果我们想要注册新的拦截器 (interceptor),我们需要实现 HttpInterceptor 接口,然后实现该接口中的 intercept 方法。

export interface HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
}

需要注意的是,请求对象和响应对象必须是不可修改的 (immutable)。因此,我们在返回请求对象前,我们需要克隆原始的请求对象。

next.handle(req) 方法使用新的请求对象,调用底层的 XHR 对象,并返回响应事件流。

响应拦截器 (Response Interceptor)

@Injectable()
class JWTInterceptor implements HttpInterceptor {

  constructor(private router: Router) {}
  
  intercept(req: HttpRequest < any > ,
    next: HttpHandler): Observable < HttpEvent < any >> {

    return next.handle(req).map(event => {
        if (event instanceof HttpResponse) {
          if (event.status === 401) {
            // JWT expired, go to login
          }
        }
        return event;
      }
    }
}

响应拦截器可以通过在 next.handle(req) 返回的流对象 (即 Observable 对象) 上应用附加的 Rx 操作符来转换响应事件流对象。

接下来要应用 JWTInterceptor 响应拦截器的最后一件事是注册该拦截器,即使用 HTTP_INTERCEPTORS 作为 token,注册 multi Provider:

[{ provide: HTTP_INTERCEPTORS, useClass: JWTInterceptor, multi: true }]

特性三 进度事件 (Progress Events)

进度事件可以用于跟踪文件上传和下载。

import {
  HttpEventType,
  HttpClient,
  HttpRequest
} from '@angular/common/http';

http.request(new HttpRequest(
  'POST',
   URL,
   body, 
  {
    reportProgress: true
  })).subscribe(event => {

  if (event.type === HttpEventType.DownloadProgress) {
    // {
    // loaded:11, // Number of bytes uploaded or downloaded.
    // total :11 // Total number of bytes to upload or download
    // }
  }

  if (event.type === HttpEventType.UploadProgress) {
    // {
    // loaded:11, // Number of bytes uploaded or downloaded.
    // total :11 // Total number of bytes to upload or download
    // }
  }

  if (event.type === HttpEventType.Response) {
    console.log(event.body);
  }
})

如果我们想要跟踪文件上传或下载的进度,在创建请求对象时,我们需要配置 {reportProgress: true} 参数。

此外在回调函数中,我们通过 event.type 来判断不同的事件类型,从进行相应的事件处理。

HttpEventType 枚举定义如下:

export enum HttpEventType {
  /**
   * 表示请求已经被发送
   */
  Sent,

  /**
   * 已接收到上传进度事件
   */
  UploadProgress,

  /**
   * 已接收到响应状态码和响应头
   */
  ResponseHeader,

  /**
   * 已接收到下载进度事件
   */
  DownloadProgress,

  /**
   * 已接收全部响应,包含响应体 
   */
  Response,

  /**
   * 用户自定义事件,来自拦截器或后端
   */
  User,
}

其实除了上面介绍三个新的功能之外,还有以下两个新的功能:

  • 基于 Angular 内部测试框架的 Post-request verification 和 flush 功能

  • 类型化,同步响应体访问,包括对 JSON 响应体类型的支持。

最后我们来通过 client_spec.ts 文件中的测试用例,来进一步感受一下上述的新特性。

其它特性

发送 GET 请求

describe('HttpClient', () => {
    let client: HttpClient = null !;
    let backend: HttpClientTestingBackend = null !;
    beforeEach(() => {
      backend = new HttpClientTestingBackend();
      client = new HttpClient(backend);
    });
    afterEach(() => { backend.verify(); }); // 请求验证
  
    describe('makes a basic request', () => {
      it('for JSON data', (done: DoneFn) => {
        client.get('/test').subscribe(res => {
          expect((res as any)['data']).toEqual('hello world');
          done();
        });
        backend.expectOne('/test').flush({'data': 'hello world'});
      });
      
      it('for an arraybuffer', (done: DoneFn) => {
        const body = new ArrayBuffer(4);
        // 还支持 {responseType: 'text'}、{responseType: 'blob'}
        client.get('/test', {responseType: 'arraybuffer'}).subscribe(res => {
          expect(res).toBe(body);
          done();
        });
        backend.expectOne('/test').flush(body);
      });
      
      it('that returns a response', (done: DoneFn) => {
        const body = {'data': 'hello world'};
        client.get('/test', {observe: 'response'}).subscribe(res => {
          expect(res instanceof HttpResponse).toBe(true);
          expect(res.body).toBe(body);
          done();
        });
        backend.expectOne('/test').flush(body);
      });
    });
});

发送 POST 请求

describe('makes a POST request', () => {
      it('with text data', (done: DoneFn) => {
        client.post('/test', 'text body', {observe: 'response', responseType: 'text'})
            .subscribe(res => {
              expect(res.ok).toBeTruthy();
              expect(res.status).toBe(200);
              done();
            });
        backend.expectOne('/test').flush('hello world');
      });
  
      it('with json data', (done: DoneFn) => {
        const body = {data: 'json body'};
        client.post('/test', body, {observe: 'response', 
          responseType: 'text'}).subscribe(res => {
          expect(res.ok).toBeTruthy();
          expect(res.status).toBe(200);
          done();
        });
        const testReq = backend.expectOne('/test');
        expect(testReq.request.body).toBe(body);
        testReq.flush('hello world');
      });
});

发送 JSONP 请求

describe('makes a JSONP request', () => {
      it('with properly set method and callback', (done: DoneFn) => {
        client.jsonp('/test', 'myCallback').subscribe(() => done());
        backend.expectOne({method: 'JSONP', url: '/test?myCallback=JSONP_CALLBACK'})
            .flush('hello world');
      });
});
查看评论

Angular 4.3 HttpClient (Angular访问 REST Web 服务) 一、Http 请求示例(Get)

链接 Angular 4.3 、HttpClien、Http请求
  • wanglui1990
  • wanglui1990
  • 2017-12-13 16:28:01
  • 1791

angular4 通过httpclient调http接口,出现access-control-allow-origin跨域问题解决办法

最近项目中在用angular4,在调试后台http接口时,会出现跨域问题,在chrom浏览器控制台报错如下 在浏览器属性中增加几行命令,即可解决该问题,具体做法如下: 右击浏览器,选择属性...
  • Tiny___
  • Tiny___
  • 2017-12-15 16:47:25
  • 441

如何使用angular4.x的HttpClient访问.net webapi

网上查阅了很多文章,基本写的都不是很完整,整理一下。从.net WebAPI与Angular两个方面来介绍。一、.net WebAPI配置.net WebAPI方面,主要是解决跨域的问题。1、修改We...
  • dickence
  • dickence
  • 2018-03-02 11:20:39
  • 166

Angular 4.3 HttpClient (Angular访问 REST Web 服务) 三、拦截器 Interceptors

拦截器新的HttpClient模块的新功能之一是拦截器的可用性。 拦截器处在应用程序和后端之间。 通过使用拦截器,可以在应用程序实际提交到后端之前转换来自应用程序的请求。 响应也是一样: 如果...
  • wanglui1990
  • wanglui1990
  • 2017-12-13 21:28:33
  • 535

Angular 4 Cookie vs Token 认证

相关链接: Angular 4 Authentication With Auth0Serverless 架构应用开发:基于 Auth0 授权的 Serverless 应用登录原文链接: Angular...
  • wanglui1990
  • wanglui1990
  • 2018-01-20 17:41:32
  • 626

Angular4 里面用post上传文件无返回数据

参考:https://valor-software.com/ng2-file-upload/
  • qq_36279445
  • qq_36279445
  • 2017-11-14 15:07:16
  • 475

【angular】解决跨域问题

angular2、angular4、angular5 及以上版本的跨域问题。通过angular自身的代理转发功能配置package.json 两种方式启动代理服务 第一种: 启动项目通过npm ...
  • xf1195718067
  • xf1195718067
  • 2017-12-07 23:29:48
  • 1081

Angular 的 $http 跨域的问题

跨域的问题一直存在开发中 情形: 即使服务端设置了 header('Access-Control-Allow-Origin: *'); header('Access-Control-A...
  • Kevin_like
  • Kevin_like
  • 2016-08-09 23:43:19
  • 983

【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解

之前 激动人心的 Angular HttpClient 这篇文章已经介绍过 HttpClient ,今天看到 angular-university 博客中介绍 HttpClient 的文章,内容...
  • xf1195718067
  • xf1195718067
  • 2017-12-02 11:45:53
  • 1266

Angular4-Http、Jsonp、rxjs请求

Http请求依赖注入import { HttpModule} from "@angular/http";页面引入Httpimport { Http} from "@angular/http"; con...
  • u013318615
  • u013318615
  • 2018-01-03 15:53:59
  • 573
    个人资料
    持之以恒
    等级:
    访问量: 2万+
    积分: 808
    排名: 6万+