全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

激动人心的 Angular HttpClient的源码解析

Angular 4.3.0-rc.0 版本已经发布🐦。在这个版本中,我们等到了一个令人兴奋的新功能 - HTTPClient API 的改进版本,以后妈妈再也不用担心我处理 HTTP 请求了😆。

HttpClient 是已有 Angular HTTP API 的演进,它在一个单独的 @angular/common/http 包中。这是为了确保现有的代码库可以缓慢迁移到新的 API。

接下来让我们开启 Angular 新版Http Client 之旅。

安装

首先,我们需要更新所有的包到 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,
}

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

  1. 基于 Angular 内部测试框架的 Post-request verification 和 flush 功能
  2. 类型化,同步响应体访问,包括对 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');
   });
});

参考资源

A Taste From The New Angular HTTP Client

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# Angular  # HttpClient  # angular5 httpclient的示例实战  # 详解使用angular的HttpClient搭配rxjs  # 浅谈Angular HttpClient简单入门  # 拦截器  # 让我们  # 不需  # 要再  # 文件上传  # 的是  # 新特性  # 这是  # 在这个  # 已有  # 我们可以  # 可以通过  # 之旅  # 一件事  # 自定义  # 它在  # 需要注意  # 回调  # 到新  # 大家多多 


相关文章: 专业网站制作服务公司,有哪些网站可以免费发布招聘信息?  高防服务器如何保障网站安全无虞?  如何零成本快速生成个人自助网站?  如何制作网站标识牌,动态网站如何制作(教程)?  建站VPS推荐:2025年高性能服务器配置指南  c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】  微信推文制作网站有哪些,怎么做微信推文,急?  c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】  电影网站制作价格表,那些提供免费电影的网站,他们是怎么盈利的?  如何在景安服务器上快速搭建个人网站?  专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  香港服务器选型指南:免备案配置与高效建站方案解析  网站制作公司排行榜,抖音怎样做个人官方网站  建站之星云端配置指南:模板选择与SEO优化一键生成  如何用PHP工具快速搭建高效网站?  如何选择高效响应式自助建站源码系统?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  如何高效完成独享虚拟主机建站?  如何通过二级域名建站提升品牌影响力?  Bpmn 2.0的XML文件怎么画流程图  建站之星安装失败:服务器环境不兼容?  如何用景安虚拟主机手机版绑定域名建站?  Android滚轮选择时间控件使用详解  如何高效配置香港服务器实现快速建站?  如何通过虚拟主机快速搭建个人网站?  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  c# await 一个已经完成的Task会发生什么  高性价比服务器租赁——企业级配置与24小时运维服务  ,石家庄四十八中学官网?  制作网站的基本流程,设计网站的软件是什么?  云南网站制作公司有哪些,云南最好的招聘网站是哪个?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  如何彻底卸载建站之星软件?  潍坊网站制作公司有哪些,潍坊哪家招聘网站好?  建站主机空间推荐 高性价比配置与快速部署方案解析  建站主机选购指南:核心配置优化与品牌推荐方案  网站微信制作软件,如何制作微信链接?  企业网站制作费用多少,企业网站空间一般需要多大,费用是多少?  建站之星如何开启自定义404页面避免用户流失?  常州企业建站如何选择最佳模板?  建站之星备案流程有哪些注意事项?  h5在线制作网站电脑版下载,h5网页制作软件?  Swift中swift中的switch 语句  建站之星代理如何获取技术支持?  建站主机CVM配置优化、SEO策略与性能提升指南  建站主机服务器选型指南与性能优化方案解析  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  南阳网站制作公司推荐,小学电子版试卷去哪里找资源好?  ,网站推广常用方法?  建站之星CMS五站合一模板配置与SEO优化指南 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。