欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

angular HttpClient 有大用 有大大用 有大大大用

Angular HttpClient请求JSON和非JSON数据

https://majing.io/posts/10000020421171



从Angular 4开始,Angular的http请求改用HttpClient。

添加HttpClientModule

首先需要引入HttpClientModule,它需要放在BrowserModule后:

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

请求JSON数据

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class ConfigService {
constructor(private http: HttpClient) { }
getData() {
return this.http.get(this.dataUrl);
}
}

HttpClient其中一个特性是默认返回的数据为json数据。,使用它返回的数据如下:

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

对于angular 4之前,则需要做json转换:

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

请求非JSON数据

如果需要返回非JSON数据,则需要在请求时设置responseType头信息为text:

getTextFile(filename: string) {
return this.http.get(filename, {responseType: 'text'})
.pipe(
tap(
data => this.log(filename, data),
error => this.logError(filename, error)
)
);
}

http.get()返回的是一个Observable<String>

来自  https://blog.csdn.net/fangquan1980/article/details/80675369








angular HttpClient get 方法获取数据

this.myhttp.get('http://192.168.2.139:9002/api/patients')方法,读取webapi。因为get方法是通过AJAX方法读取数据的,所以服务器要可以跨域访问,具体方法查询webapi文章
复制代码
复制代码
 1 import { Component, OnInit } from '@angular/core';
 2 import { HttpClient } from '@angular/common/http';
 3 import { Patient } from './app.patient.server';
 4 @Component({
 5   selector: 'app-root',
 6   templateUrl: './app.component.html',
 7   styleUrls: ['./app.component.css']
 8 })
 9 
10 export class AppComponent implements OnInit {
11   title = 'angular4.3';
12   results: string[];
13   myPatientList: Patient[] = [];
14 
15 16   constructor(
17     private myhttp: HttpClient
18   ) { }
19 
20   ngOnInit(): void {
21     this.myhttp.get('http://192.168.2.139:9002/api/patients')
22       .subscribe(data => {
23         this.myPatientList = (<any>data).map(u => new Patient({
24           id: u.PatientId,
25           FirstName: u.Details.FirstName,
26           LastName: u.Details.LastName,
27           MiddleName: u.Details.MiddleName,
28           BirthDate: u.Details.BirthDate,
29           Gender: u.Details.Gender,
30           PhoneNumber: u.PersonalInfo.PhoneNumberPrimary,
31           ZIPCODE: u.PersonalInfo.ZIPCODE,
32           City: u.PersonalInfo.City,
33           Street: u.PersonalInfo.Street,
34           EmailAddress: u.PersonalInfo.EmailAddressPrimary,
35           CitizenServiceNumber: u.PersonalInfo.ServiceNumber
36         }));
37 38 }); 39 } 40 }
复制代码
复制代码
(<any>data).map()方法直接把读取data数据转换成实体类。
【注:需要查看自己的json文件,对应好结构】 网上很多json都是以results[]开头。以所用(<any>data).results.map() 这个问题真的卡了我很久,在同事长庆的帮助下才得以解决。

实体类代码,如下:
复制代码
复制代码
 1 export class Patient {
 2     id: string;
 3     FirstName: string;
 4     LastName: string;
 5     MiddleName: string;
 6     BirthDate: string;
 7     Gender: string;
 8     PhoneNumber: string;
 9     ZIPCODE: string;
10     City: string;
11     Street: string;
12     EmailAddress: string;
13     CitizenServiceNumber: string;
14 
15     public constructor(
16       fields?: {
17         id: string,
18         FirstName: string,
19         LastName: string,
20         MiddleName: string,
21         BirthDate: string,
22         Gender: string,
23         PhoneNumber: string,
24         ZIPCODE: string,
25         City: string,
26         Street: string,
27         EmailAddress: string,
28         CitizenServiceNumber: string
29       }) {
30       // tslint:disable-next-line:curly
31       if (fields) Object.assign(this, fields);
32     }
33 
34     getFullName(): string {
35       return this.FirstName + ' ' + this.LastName;
36     }
37   }
复制代码
复制代码

前台调用很简单,直接读取实体类就可以了

复制代码
复制代码
 1 <div style="text-align:center">
 2   <h1>
 3     Welcome to {{title}}!
 4   </h1>
 5   {{results}}
 6   <h2>ngfor</h2>
 7   <ul>
 8       <li *ngFor="let myPatient of myPatientList" >
 9           id:{{myPatient.id}} FirstName :{{myPatient.FirstName}}
10       </li>
11 </ul>
12 </div>
复制代码
复制代码

显示如下图:

注:这个用法写的还很简单,还需要传参数,加头文件之类的方法,不过已经可以基本的读取数据了。

转自:http://www.cnblogs.com/cxd1008/p/7685999.html

分类: Angular


来自  https://www.cnblogs.com/yangfantianxia/p/8053251.html



Angular之服务、HttpClient请求数据、subscribe解决请求异步

字数 257阅读 3835

1.使用
某些共同的功能可以作为服务,比如说使用一个服务来定义一个URL,可以作用于全局,服务是可以在任何组件中单独注入的。

2.特性

1)服务是单例的,也就是实例化一次贯穿于应用的整个生命周期,常驻内存
,所以不能定义太多的服务。

2)全局属性 全局行为,可以在组件之间的数据通信中使用,但是安全性不高。也可以使用storage进行组件之间的数据传递。

3)在任何组件中可以单独注入

4)服务中是不可以再构建服务的

5)所有的服务对象实例化必须放在constructor的小括号里

3.代码

4.HttpClient
安装:imports import导入

发起请求,请求json

5.subscribe
解决异步的三大方法
。回调callback
。承诺promise
。subscribe

现在最主流的就是subscribe

private http:HttpClient;
this.http.get('json').subscribe(data=>
{ 
   console.log(data)
},
error=>{
  console.log('error');
})

1人点赞


来自  https://www.jianshu.com/p/2d0851b24974


Angular7 HttpClient处理多个请求

1. MergeMap - 串联请求

  • 后一个请求需要前一个请求的返回结果时,需要使用串联请求。

  • 可以使用MergeMap实现, 优势是减少嵌套,优化代码;

代码如下:


import {HttpClient} from '@angular/common/http';
import {mergeMap} from 'rxjs';

@Component({
   ...
})
export class HttpComponent implements OnInit {


  constructor(private http: HttpClient) { }


  ngOnInit() {
    // 串联请求, 前面请求会影响后面的请求,前面请求未请求到,后面请求中断;
    const httpThis = this;
    httpThis.http.get('/api/token').
      pipe(
      map(token => {
        return token;
      }),
      mergeMap((tokenRes: any) => { // tokenRes接收的是token数据
        return httpThis.http.get(`/api/user?token=${tokenRes}`)
          .pipe((user) => {
            return user;
          });
      }),
      mergeMap((userRes: any) => { // userRes接收的是user数据
        return httpThis.http.get(`api/data?user=${userRes}`)
          .pipe((data) => {
            return data;
          });
      }))
      .subscribe((resp) => { // resp接收的是data数据
        console.log('最终结果resp是最后一个mergeMap的data');
      });
  }
}

2. ForkJoin - 并联请求

  • 多个请求,无所谓先后顺序,等到全部请求完成后执行一定的操作时,需要使用并联请求;

  • 可以使用ForkJoin,和promise方法效果一样,好处是:可以减少嵌套,优化代码;

代码如下:


import {HttpClient} from '@angular/common/http';
import {forkJoin} from 'rxjs';

@Component({
   ...
})


export class HttpComponent implements OnInit {


  constructor(private http: HttpClient) { }


  ngOnInit() {
     
    // 并联请求
    const post1 = this.requestData1();
    const post2 = this.requestData2();
    forkJoin([post1, post2])
      .subscribe((data: any) => {
        const postResult1 = data[0]; // '/api/post1的返回结果'
        const postResult2 = data[1]; // '/api/post2的返回结果'
      });
  }


  // 并联请求1
  requestData1() {
    return this.http.get('/api/post1')
      .pipe((data) => {
        return data;
      });
  }


  // 并联请求2
  requestData2() {
    return this.http.get('/api/post2')
      .pipe((data) => {
        return data;
      });
  }
}
分类: Angular


来自   https://www.cnblogs.com/zero-zm/p/9859102.html



Angular HTTP Client 快速入门

之前 激动人心的 Angular HttpClient 这篇文章已经介绍过 HttpClient ,今天看到 angular-university 博客中介绍 HttpClient 的文章,内容很详细,我就简单做了整理。有兴趣的话,建议直接阅读 原文

HttpClientModule 应用

导入新的 HTTP Module

  1. import {HttpClientModule} from '@angular/common/http';
  2. @NgModule({
  3. declarations: [
  4. AppComponent
  5. ],
  6. imports: [
  7. BrowserModule,
  8. HttpClientModule
  9. ],
  10. providers: [],
  11. bootstrap: [AppComponent]
  12. })
  13. export class AppModule {}

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

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

现在我们可以这样写:

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

发送 Get 请求

  1. import {Component, OnInit} from '@angular/core';
  2. import {Observable} from "rxjs/Observable";
  3. import {HttpClient} from "@angular/common/http";
  4. import * as _ from 'lodash';
  5. interface Course {
  6. description: string;
  7. courseListIcon:string;
  8. iconUrl:string;
  9. longDescription:string;
  10. url:string;
  11. }
  12. @Component({
  13.  selector: 'app-root',
  14.  template: `
  15.      <ul *ngIf="courses$ | async as courses else noData">
  16.          <li *ngFor="let course of courses">
  17.              {{course.description}}
  18.          </li>
  19.      </ul>
  20.      <ng-template #noData>No Data Available</ng-template>
  21.  `})
  22. export class AppComponent implements OnInit {
  23. courses$: Observable<any>;
  24. constructor(private http:HttpClient) {}
  25. ngOnInit() {
  26. this.courses$ = this.http
  27. .get("https://angular-http-guide.firebaseio.com/courses.json")
  28. .map(data => _.values(data))
  29. .do(console.log);
  30. }
  31. }

设置查询参数

假设发送 Get 请求时,需要设置对应的查询参数,预期的 URL 地址如下:

https://angular-http-guide.firebaseio.com/courses.json?orderBy="$key"&limitToFirst=1

创建 HttpParams 对象

  1. import {HttpParams} from "@angular/common/http";
  2. const params = new HttpParams()
  3. .set('orderBy', '"$key"')
  4. .set('limitToFirst', "1");
  5. this.courses$ = this.http
  6. .get("/courses.json", {params})
  7. .do(console.log)
  8. .map(data => _.values(data))

需要注意的是,我们通过链式语法调用 set() 方法,构建 HttpParams 对象。这是因为 HttpParams 对象是不可变的,通过 set()方法可以防止该对象被修改。

每当调用 set() 方法,将会返回包含新值的 HttpParams 对象,因此如果使用下面的方式,将不能正确的设置参数。

  1. const params = new HttpParams();
  2. params.set('orderBy', '"$key"')
  3. params.set('limitToFirst', "1");

使用 fromString 语法

const paramsnew HttpParams({fromString: 'orderBy="$key"&limitToFirst=1'});

使用 request() API

  1. const params = new HttpParams({fromString: 'orderBy="$key"&limitToFirst=1'});
  2. this.courses$ = this.http
  3. .request(
  4. "GET",
  5. "/courses.json",
  6. {
  7. responseType:"json",
  8. params
  9. })
  10. .do(console.log)
  11. .map(data => _.values(data));

设置 HTTP Headers

  1. const headers = new HttpHeaders().set("X-CustomHeader", "custom header value");
  2. this.courses$ = this.http
  3. .get(
  4. "/courses.json",
  5. {headers})
  6. .do(console.log)
  7. .map(data => _.values(data));

发送 Put 请求

  1. httpPutExample() {
  2. const headers = new HttpHeaders().set("Content-Type", "application/json");
  3. this.http.put("/courses/-KgVwECOnlc-LHb_B0cQ.json",
  4. {
  5. "courseListIcon": ".../main-page-logo-small-hat.png",
  6. "description": "Angular Tutorial For Beginners TEST",
  7. "iconUrl": ".../angular2-for-beginners.jpg",
  8. "longDescription": "...",
  9. "url": "new-value-for-url"
  10. },
  11. {headers})
  12. .subscribe(
  13. val => {
  14. console.log("PUT call successful value returned in body",
  15. val);
  16. },
  17. response => {
  18. console.log("PUT call in error", response);
  19. },
  20. () => {
  21. console.log("The PUT observable is now completed.");
  22. }
  23. );
  24. }

发送 Patch 请求

  1. httpPatchExample() {
  2. this.http.patch("/courses/-KgVwECOnlc-LHb_B0cQ.json",
  3. {
  4. "description": "Angular Tutorial For Beginners PATCH TEST",
  5. })
  6. .subscribe(
  7. (val) => {
  8. console.log("PATCH call successful value returned in body",
  9. val);
  10. },
  11. response => {
  12. console.log("PATCH call in error", response);
  13. },
  14. () => {
  15. console.log("The PATCH observable is now completed.");
  16. });
  17. }

发送 Delete 请求

  1. httpDeleteExample() {
  2. this.http.delete("/courses/-KgVwECOnlc-LHb_B0cQ.json")
  3. .subscribe(
  4. (val) => {
  5. console.log("DELETE call successful value returned in body",
  6. val);
  7. },
  8. response => {
  9. console.log("DELETE call in error", response);
  10. },
  11. () => {
  12. console.log("The DELETE observable is now completed.");
  13. });
  14. }

发送 Post 请求

  1. httpPostExample() {
  2. this.http.post("/courses/-KgVwECOnlc-LHb_B0cQ.json",
  3. {
  4. "courseListIcon": "...",
  5. "description": "TEST",
  6. "iconUrl": "..",
  7. "longDescription": "...",
  8. "url": "new-url"
  9. })
  10. .subscribe(
  11. (val) => {
  12. console.log("POST call successful value returned in body",
  13. val);
  14. },
  15. response => {
  16. console.log("POST call in error", response);
  17. },
  18. () => {
  19. console.log("The POST observable is now completed.");
  20. });
  21. }

避免重复请求

  1. duplicateRequestsExample() {
  2. const httpGet$ = this.http
  3. .get("/courses.json")
  4. .map(data => _.values(data));
  5. httpGet$.subscribe(
  6. (val) => console.log("logging GET value", val)
  7. );
  8. this.courses$ = httpGet$;
  9. }

在上面例子中,我们正在创建了一个 HTTP observable 对象 httpGet$,接着我们直接订阅该对象。然后,我们把 httpGet$ 对象赋值给 courses$ 成员变量,最后在模板中使用 async 管道订阅该对象。

这将导致发送两个 HTTP 请求,在这种情况下,请求显然是重复的,因为我们只希望从后端查询一次数据。为了避免发送冗余的请求,我们可以使用 RxJS 提供的 shareReplay 操作符:

  1. // put this next to the other RxJs operator imports
  2. import 'rxjs/add/operator/shareReplay';
  3. const httpGet$ = this.http
  4. .get("/courses.json")
  5. .map(data => _.values(data))
  6. .shareReplay();

并行发送多个请求

并行发送 HTTP 请求的一种方法是使用 RxJs 中的 forkjoin 操作符:

  1. import 'rxjs/add/observable/forkJoin';
  2. parallelRequests() {
  3. const parallel$ = Observable.forkJoin(
  4. this.http.get('/courses/-KgVwEBq5wbFnjj7O8Fp.json'),
  5. this.http.get('/courses/-KgVwECOnlc-LHb_B0cQ.json')
  6. );
  7. parallel$.subscribe(
  8. values => {
  9. console.log("all values", values)
  10. }
  11. );
  12. }

顺序发送 Http 请求

  1. sequentialRequests() {
  2. const sequence$ = this.http.get<Course>('/courses/-KgVwEBq5wbFnjj7O8Fp.json')
  3. .switchMap(course => {
  4. course.description+= ' - TEST ';
  5. return this.http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json', course)
  6. });
  7. sequence$.subscribe();
  8. }

获取顺序发送 Http 请求的结果

  1. sequentialRequests() {
  2. const sequence$ = this.http.get<Course>('/courses/-KgVwEBq5wbFnjj7O8Fp.json')
  3. .switchMap(course => {
  4. course.description+= ' - TEST ';
  5. return this.http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json', course)
  6. },
  7. (firstHTTPResult, secondHTTPResult)  => [firstHTTPResult, secondHTTPResult]);
  8. sequence$.subscribe(values => console.log("result observable ", values) );
  9. }

请求异常处理

  1. throwError() {
  2. this.http
  3. .get("/api/simulate-error")
  4. .catch( error => {
  5. // here we can show an error message to the user,
  6. // for example via a service
  7. console.error("error catched", error);
  8. return Observable.of({description: "Error Value Emitted"});
  9. })
  10. .subscribe(
  11. val => console.log('Value emitted successfully', val),
  12. error => {
  13. console.error("This line is never called ",error);
  14. },
  15. () => console.log("HTTP Observable completed...")
  16. );
  17. }

当发生异常时,控制台的输出结果:

  1. Error catched
  2. HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/api/simulate-error", ok: false, … }
  3. Value emitted successfully {description: "Error Value Emitted"}
  4. HTTP Observable completed...

Http 拦截器

定义拦截器

  1. import {Injectable} from "@angular/core";
  2. import {HttpEvent, HttpHandler, HttpInterceptor} from "@angular/common/http";
  3. import {HttpRequest} from "@angular/common/http";
  4. import {Observable} from "rxjs/Observable";
  5. @Injectable()
  6. export class AuthInterceptor implements HttpInterceptor {
  7. constructor(private authService: AuthService) {
  8. }
  9. intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  10. const clonedRequest = req.clone({
  11. headers: req.headers.set('X-CustomAuthHeader', authService.getToken())
  12. });
  13. console.log("new headers", clonedRequest.headers.keys());
  14. return next.handle(clonedRequest);
  15. }
  16. }

配置拦截器

  1. @NgModule({
  2. declarations: [
  3. AppComponent
  4. ],
  5. imports: [
  6. BrowserModule,
  7. HttpClientModule
  8. ],
  9. providers: [
  10. [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ]
  11. ],
  12. bootstrap: [AppComponent]
  13. })
  14. export class AppModule { }

Http 进度事件

  1. longRequest() {
  2. const request = new HttpRequest(
  3. "POST", "/api/test-request", {},
  4. {reportProgress: true});
  5. this.http.request(request)
  6. .subscribe(
  7. event => {
  8. if (event.type === HttpEventType.DownloadProgress) {
  9. console.log("Download progress event", event);
  10. }
  11. if (event.type === HttpEventType.UploadProgress) {
  12. console.log("Upload progress event", event);
  13. }
  14. if (event.type === HttpEventType.Response) {
  15. console.log("response received...", event.body);
  16. }
  17. }
  18. );
  19. }

上面示例运行后,控制台的可能的输出结果:

  1. Upload progress event Object {type: 1, loaded: 2, total: 2}
  2. Download progress event Object {type: 3, loaded: 31, total: 31}
  3. Response Received... Object {description: "POST Response"}



来自   https://blog.csdn.net/xiaoxinshuaiga/article/details/79915930



请先查看上一篇文章HttpClient配置,之后在进行。

使用

this.myhttp.get('http://192.168.2.139:9002/api/patients')方法,读取webapi。因为get方法是通过AJAX方法读取数据的,所以服务器要可以跨域访问,具体方法查询webapi文章
复制代码
 1 import { Component, OnInit } from '@angular/core';
 2 import { HttpClient } from '@angular/common/http';
 3 import { Patient } from './app.patient.server';
 4 @Component({
 5   selector: 'app-root',
 6   templateUrl: './app.component.html',
 7   styleUrls: ['./app.component.css']
 8 })
 9 
10 export class AppComponent implements OnInit {
11   title = 'angular4.3';
12   results: string[];
13   myPatientList: Patient[] = [];
14 
15 16   constructor(
17     private myhttp: HttpClient
18   ) { }
19 
20   ngOnInit(): void {
21     this.myhttp.get('http://192.168.2.139:9002/api/patients')
22       .subscribe(data => {
23         this.myPatientList = (<any>data).map(u => new Patient({
24           id: u.PatientId,
25           FirstName: u.Details.FirstName,
26           LastName: u.Details.LastName,
27           MiddleName: u.Details.MiddleName,
28           BirthDate: u.Details.BirthDate,
29           Gender: u.Details.Gender,
30           PhoneNumber: u.PersonalInfo.PhoneNumberPrimary,
31           ZIPCODE: u.PersonalInfo.ZIPCODE,
32           City: u.PersonalInfo.City,
33           Street: u.PersonalInfo.Street,
34           EmailAddress: u.PersonalInfo.EmailAddressPrimary,
35           CitizenServiceNumber: u.PersonalInfo.ServiceNumber
36         }));
37 38      }); 39  } 40 }
复制代码
(<any>data).map()方法直接把读取data数据转换成实体类。
【注:需要查看自己的json文件,对应好结构】 网上很多json都是以results[]开头。以所用(<any>data).results.map() 这个问题真的卡了我很久,在同事长庆的帮助下才得以解决。

实体类代码,如下:
复制代码
 1 export class Patient {
 2     id: string;
 3     FirstName: string;
 4     LastName: string;
 5     MiddleName: string;
 6     BirthDate: string;
 7     Gender: string;
 8     PhoneNumber: string;
 9     ZIPCODE: string;
10     City: string;
11     Street: string;
12     EmailAddress: string;
13     CitizenServiceNumber: string;
14 
15     public constructor(
16       fields?: {
17         id: string,
18         FirstName: string,
19         LastName: string,
20         MiddleName: string,
21         BirthDate: string,
22         Gender: string,
23         PhoneNumber: string,
24         ZIPCODE: string,
25         City: string,
26         Street: string,
27         EmailAddress: string,
28         CitizenServiceNumber: string
29       }) {
30       // tslint:disable-next-line:curly
31       if (fields) Object.assign(this, fields);
32     }
33 
34     getFullName(): string {
35       return this.FirstName + ' ' + this.LastName;
36     }
37   }
复制代码

前台调用很简单,直接读取实体类就可以了

复制代码
 1 <div style="text-align:center">
 2   <h1>
 3     Welcome to {{title}}!
 4   </h1>
 5   {{results}}
 6   <h2>ngfor</h2>
 7   <ul>
 8       <li *ngFor="let myPatient of myPatientList" >
 9           id:{{myPatient.id}} FirstName :{{myPatient.FirstName}}
10       </li>
11 </ul>
12 </div>
复制代码

显示如下图:

注:这个用法写的还很简单,还需要传参数,加头文件之类的方法,不过已经可以基本的读取数据了。

来自  https://www.cnblogs.com/cxd1008/p/7685999.html


Angular(7) 学习资料 (8)HttpClient

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_20282263/article/details/88038039

HttpClient

简介

现代浏览器支持使用两种不同的 API 发起 HTTP 请求:XMLHttpRequest 接口和 fetch() API。

@angular/common/http 中的 HttpClient 类为 Angular 应用程序提供了一个简化的 API 来实现 HTTP 客户端功能。它基于浏览器提供的 XMLHttpRequest 接口。

HttpClient 带来的其它优点包括:

  • 可测试性

  • 强类型的请求和响应对象

  • 发起请求与接收响应时的拦截器支持

  • 更好的、基于可观察(Observable)对象的 API

  • 流式错误处理机制

基础用法

  • 导入 HttpClientModule

  • 注入 HttpClient

  • 最佳实践:把数据展现逻辑从数据访问逻辑中拆分出去,也就是说把数据访问逻辑包装进一个单独的服务中, 并且在组件中把数据访问逻辑委托给这个服务

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

// 注入 HttpClient
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class ConfigService {
  constructor(private http: HttpClient) { }
}


// 注入服务并使用
showConfig() {
  this.configService.getConfig()
    .subscribe((data: Config) => this.config = {
        heroesUrl: data['heroesUrl'],
        textfile:  data['textfile']
    });
}

语法糖

  • http.requres(method: string, url: string, options: object)

  • http.delete(url: string, options: object)

  • http.get(url: string, options: object)

  • http.head(url: string, options: object)

  • http.jsonp(url: string, callbackParam: string) : 必须安装一个合适的拦截器(比如借助 HttpClientJsonpModule)。 如果没有这个拦截器,JSONP 请求就可能被后端拒绝。

  • http.options(url: string, options: object)

  • http.patch(url: string, body: any options: object)

  • http.put(url: string, body: any options: object)

  • http.post(url: string, body: any options: object)

参数详解

  • options.body?: any : 请求体

  • options.headers?: HttpHeaders | { [header: string]: string | string[]; } : 请求头

  • options.params?: HttpParams | { [param: string]: string | string[]; } : 请求 url 的参数

  • options.reportProgress?: boolean : 该请求是否应该暴露出进度事件

  • options.responseType?: "arraybuffer" | "blob" | "text" | "json" : 响应数据的类型

  • options.withCredentials?: boolean : 跨域请求是否带 cookies

  • options.observe?: "body" : observe 的值决定 request() 的返回值类型,这取决于消费方在订阅时对哪些东西感兴趣。 当它的值是 events 时,它将返回一个 Observable<HttpEvent>,以表示原始的 HTTPEvent 流,默认还包括网络通讯进度事件。 当它的值是 response 时,它将返回一个 Observable<HttpResponse<T>>,HttpResponse 的 T 参数 取决于 responseType 以及可选提供的类型参数。 当它的值是 body 时,它将返回一个 body 类型为 T 的 Observable<T> 对象

拦截器

HTTP 拦截机制是 @angular/common/http 中的主要特性之一。 使用这种拦截机制,你可以声明一些拦截器,用它们监视和转换从应用发送到服务器的 HTTP 请求。拦截器可以用一种常规的、标准的方式对每一次 HTTP 的请求/响应任务执行从认证到记日志等很多种隐式任务。

定义拦截器

import { Injectable } from '@angular/core'
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'
import { Observable } from 'rxjs'
@Injectable({
  providedIn: 'root'
})
export class InterceptorService implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authReq = req.clone({
      headers: req.headers.set('Authorization', 'token <your GitHub token>')
    })
    return next.handle(authReq)
  }
}

  • req : 要处理的外发请求。虽然拦截器有能力改变请求和响应,但 HttpRequest 和 HttpResponse 实例的属性却是只读(readonly)的, 因此让它们基本上是不可变的。要想修改该请求,就要先克隆它,并修改这个克隆体,然后再把这个克隆体传给 next.handle()。

  • next : 拦截器链中的下一个拦截器,如果链中没有其它拦截器了,则为后端 HTTP 调用。大多数的拦截器都会调用 next.handle(),以便这个请求流能走到下一个拦截器,并最终传给后端处理器。 拦截器也可以不调用 next.handle(),使这个链路短路,并返回一个带有人工构造出来的服务器响应的自己的 Observable

注入拦截器

import { NgModule } from '@angular/core'
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'
import { InterceptorService } from './service/interceptor.service'
import { AppComponent } from './app.component'

@NgModule({
  providers: [
    HttpClientModule,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: InterceptorService,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

  • 由于拦截器是 HttpClient 服务的(可选)依赖,所以你必须在提供 HttpClient 的同一个(或其各级父注入器)注入器中提供这些拦截器。 那些在 DI 创建完 HttpClient 之后再提供的拦截器将会被忽略。

  • 由于在 AppModule 中导入了 HttpClientModule,导致本应用在其根注入器中提供了 HttpClient。所以你也同样要在 AppModule 中提供这些拦截器。

  • 要想在整个应用中使用 HttpInterceptors 的同一个实例,就只能在 AppModule 模块中导入 HttpClientModule,并且把拦截器都添加到应用的根注入器中。 如果你在不同的模块中多次导入 HttpClientModule,则每次导入都会创建 HttpClientModule 的一个新复本,它将会覆盖根模块上提供的那些拦截器

  • Angular 会按照你提供它们的顺序应用这些拦截器。 如果你提供拦截器的顺序是先 A,再 B,再 C,那么请求阶段的执行顺序就是 A->B->C,而响应阶段的执行顺序则是 C->B->A

XSRF 防护

  • HttpClient 支持一种通用的机制来防范 XSRF 攻击。当执行 HTTP 请求时,一个拦截器会从 cookie 中读取 XSRF 令牌(默认名字为 XSRF-TOKEN),并且把它设置为一个 HTTP 头 X-XSRF-TOKEN,由于只有运行在你自己的域名下的代码才能读取这个 cookie,因此后端可以确认这个 HTTP 请求真的来自你的客户端应用,而不是攻击者。

  • 如果你的后端服务中对 XSRF 令牌的 cookie 或 头使用了不一样的名字,就要使用 HttpClientXsrfModule.withConfig() 来覆盖掉默认值。

imports: [
  HttpClientModule,
  HttpClientXsrfModule.withOptions({
    cookieName: 'My-Xsrf-Cookie',
    headerName: 'My-Xsrf-Header'
  })
]

来自  https://blog.csdn.net/qq_20282263/article/details/88038039

普通分类: