【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
2017-12-02 11:45
681 查看
之前 激动人心的 Angular HttpClient 这篇文章已经介绍过 HttpClient ,今天看到
angular-university 博客中介绍 HttpClient 的文章,内容很详细,我就简单做了整理。有兴趣的话,建议直接阅读
原文。
HttpClientModule 应用 导入新的 HTTP Module
需要注意的是,现在 JSON 是默认的数据格式,我们不需要再进行显式的解析。即我们不需要再使用以下代码:
现在我们可以这
Get 请求
设置查询参数
假设发送 Get 请求时,需要设置对应的查询参数,预期的 URL 地址如下:
创建 HttpParams 对象
需要注意的是,我们通过链式语法调用 set() 方法,构建 HttpParams 对象。这是因为 HttpParams 对象是不可变的,通过 set() 方法可以防止该对象被修改。
每当调用 set() 方法,将会返回包含新值的 HttpParams 对象,因此如果使用下面的方式,将不能正确的设置参数。
发送 Put 请求
发送 Patch 请求
发送 Delete 请求
发送 Post 请求
避免重复请求
在上面例子中,我们正在创建了一个 HTTP observable 对象 httpGet,接着我们直接订阅该对象。然后,我们把httpGet 对象赋值给 courses$ 成员变量,最后在模板中使用 async 管道订阅该对象。
这将导致发送两个 HTTP 请求,在这种情况下,请求显然是重复的,因为我们只希望从后端查询一次数据。为了避免发送冗余的请求,我们可以使用 RxJS 提供的 shareReplay 操作符:
并行发送多个请求
并行发送 HTTP 请求的一种方法是使用 RxJs 中的 forkjoin 操作符:
顺序发送 Http 请求
获取顺序发送 Http 请求的结果
请求异常处理
当发生异常时,控制台的输出结果:
Http 拦截器
定义拦截器
配置拦截器
Http 进度事件
上面示例运行后,控制台的可能的输出结果:
angular、spring cloud 开源实战项目源码:https://gitee.com/xfdm/FCat
QQ群:549141844
代码持续更新…
angular-university 博客中介绍 HttpClient 的文章,内容很详细,我就简单做了整理。有兴趣的话,建议直接阅读
原文。
HttpClientModule 应用 导入新的 HTTP Module
import {HttpClientModule} from '@angular/common/http'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule {}
需要注意的是,现在 JSON 是默认的数据格式,我们不需要再进行显式的解析。即我们不需要再使用以下代码:
http.get(url).map(res => res.json()).subscribe(...)
现在我们可以这
http.get(url).subscribe(...)
Get 请求
import {Component, OnInit} from '@angular/core'; import {Observable} from "rxjs/Observable"; import {HttpClient} from "@angular/common/http"; import * as _ from 'lodash'; interface Course { description: string; courseListIcon:string; iconUrl:string; longDescription:string; url:string; } @Component({ selector: 'app-root', template: ` <ul *ngIf="courses$ | async as courses else noData"> <li *ngFor="let course of courses"> {{course.description}} </li> </ul> <ng-template #noData>No Data Available</ng-template> `}) export class AppComponent implements OnInit { courses$: Observable<any>; constructor(private http:HttpClient) {} ngOnInit() { this.courses$ = this.http .get("https://angular-http-guide.firebaseio.com/courses.json") .map(data => _.values(data)) .do(console.log); } }
设置查询参数
假设发送 Get 请求时,需要设置对应的查询参数,预期的 URL 地址如下:
https://angular-http-guide.firebaseio.com/courses.json?orderBy="$key"&limitToFirst=1
创建 HttpParams 对象
import {HttpParams} from "@angular/common/http"; const params = new HttpParams() .set('orderBy', '"$key"') .set('limitToFirst', "1"); this.courses$ = this.http .get("/courses.json", {params}) .do(console.log) .map(data => _.values(data))
需要注意的是,我们通过链式语法调用 set() 方法,构建 HttpParams 对象。这是因为 HttpParams 对象是不可变的,通过 set() 方法可以防止该对象被修改。
每当调用 set() 方法,将会返回包含新值的 HttpParams 对象,因此如果使用下面的方式,将不能正确的设置参数。
const params = new HttpParams(); params.set('orderBy', '"$key"') params.set('limitToFirst', "1"); 使用 fromString 语法 const params = new HttpParams({fromString: 'orderBy="$key"&limitToFirst=1'}); 使用 request() API const params = new HttpParams({fromString: 'orderBy="$key"&limitToFirst=1'}); this.courses$ = this.http .request( "GET", "/courses.json", { responseType:"json", params }) .do(console.log) .map(data => _.values(data)); 设置 HTTP Headers const headers = new HttpHeaders().set("X-CustomHeader", "custom header value"); this.courses$ = this.http .get( "/courses.json", {headers}) .do(console.log) .map(data => _.values(data));
发送 Put 请求
httpPutExample() { const headers = new HttpHeaders().set("Content-Type", "application/json"); this.http.put("/courses/-KgVwECOnlc-LHb_B0cQ.json", { "courseListIcon": ".../main-page-logo-small-hat.png", "description": "Angular Tutorial For Beginners TEST", "iconUrl": ".../angular2-for-beginners.jpg", "longDescription": "...", "url": "new-value-for-url" }, {headers}) 4000 .subscribe( val => { console.log("PUT call successful value returned in body", val); }, response => { console.log("PUT call in error", response); }, () => { console.log("The PUT observable is now completed."); } ); }
发送 Patch 请求
httpPatchExample() { this.http.patch("/courses/-KgVwECOnlc-LHb_B0cQ.json", { "description": "Angular Tutorial For Beginners PATCH TEST", }) .subscribe( (val) => { console.log("PATCH call successful value returned in body", val); }, response => { console.log("PATCH call in error", response); }, () => { console.log("The PATCH observable is now completed."); }); }
发送 Delete 请求
httpDeleteExample() { this.http.delete("/courses/-KgVwECOnlc-LHb_B0cQ.json") .subscribe( (val) => { console.log("DELETE call successful value returned in body", val); }, response => { console.log("DELETE call in error", response); }, () => { console.log("The DELETE observable is now completed."); }); }
发送 Post 请求
httpPostExample() { this.http.post("/courses/-KgVwECOnlc-LHb_B0cQ.json", { "courseListIcon": "...", "description": "TEST", "iconUrl": "..", "longDescription": "...", "url": "new-url" }) .subscribe( (val) => { console.log("POST call successful value returned in body", val); }, response => { console.log("POST call in error", response); }, () => { console.log("The POST observable is now completed."); }); }
避免重复请求
duplicateRequestsExample() { const httpGet$ = this.http .get("/courses.json") .map(data => _.values(data)); httpGet$.subscribe( (val) => console.log("logging GET value", val) ); this.courses$ = httpGet$; }
在上面例子中,我们正在创建了一个 HTTP observable 对象 httpGet,接着我们直接订阅该对象。然后,我们把httpGet 对象赋值给 courses$ 成员变量,最后在模板中使用 async 管道订阅该对象。
这将导致发送两个 HTTP 请求,在这种情况下,请求显然是重复的,因为我们只希望从后端查询一次数据。为了避免发送冗余的请求,我们可以使用 RxJS 提供的 shareReplay 操作符:
// put this next to the other RxJs operator imports import 'rxjs/add/operator/shareReplay'; const httpGet$ = this.http .get("/courses.json") .map(data => _.values(data)) .shareReplay();
并行发送多个请求
并行发送 HTTP 请求的一种方法是使用 RxJs 中的 forkjoin 操作符:
import 'rxjs/add/observable/forkJoin'; parallelRequests() { const parallel$ = Observable.forkJoin( this.http.get('/courses/-KgVwEBq5wbFnjj7O8Fp.json'), this.http.get('/courses/-KgVwECOnlc-LHb_B0cQ.json') ); parallel$.subscribe( values => { console.log("all values", values) } ); }
顺序发送 Http 请求
sequentialRequests() { const sequence$ = this.http.get<Course>('/courses/-KgVwEBq5wbFnjj7O8Fp.json') .switchMap(course => { course.description+= ' - TEST '; return this.http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json', course) }); sequence$.subscribe(); }
获取顺序发送 Http 请求的结果
sequentialRequests() { const sequence$ = this.http.get<Course>('/courses/-KgVwEBq5wbFnjj7O8Fp.json') .switchMap(course => { course.description+= ' - TEST '; return this.http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json', course) }, (firstHTTPResult, secondHTTPResult) => [firstHTTPResult, secondHTTPResult]); sequence$.subscribe(values => console.log("result observable ", values) ); }
请求异常处理
throwError() { this.http .get("/api/simulate-error") .catch( error => { // here we can show an error message to the user, // for example via a service console.error("error catched", error); return Observable.of({description: "Error Value Emitted"}); }) .subscribe( val => console.log('Value emitted successfully', val), error => { console.error("This line is never called ",error); }, () => console.log("HTTP Observable completed...") ); }
当发生异常时,控制台的输出结果:
Error catched HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/api/simulate-error", ok: false, … } Value emitted successfully {description: "Error Value Emitted"} HTTP Observable completed...
Http 拦截器
定义拦截器
import {Injectable} from "@angular/core"; import {HttpEvent, HttpHandler, HttpInterceptor} from "@angular/common/http"; import {HttpRequest} from "@angular/common/http"; import {Observable} from "rxjs/Observable"; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private authService: AuthService) { } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const clonedRequest = req.clone({ headers: req.headers.set('X-CustomAuthHeader', authService.getToken()) }); console.log("new headers", clonedRequest.headers.keys()); return next.handle(clonedRequest) /*.do((event: any) => { console.log(event); if (event instanceof HttpResponse) { if (event.status === 403) { // 权限处理 console.log('401权限受限'); }else if (event.status === 200) { // 业务层级错误处理 console.log('200业务层级错误处理'); }else if (event.status === 404) { console.log('404接口不存在。'); } } return event; });*/ } }
配置拦截器
@NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [ [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ] ], bootstrap: [AppComponent] }) export class AppModule { }
Http 进度事件
longRequest() { const request = new HttpRequest( "POST", "/api/test-request", {}, {reportProgress: true}); this.http.request(request) .subscribe( event => { if (event.type === HttpEventType.DownloadProgress) { console.log("Download progress event", event); } if (event.type === HttpEventType.UploadProgress) { console.log("Upload progress event", event); } if (event.type === HttpEventType.Response) { console.log("response received...", event.body); } } ); }
上面示例运行后,控制台的可能的输出结果:
Upload progress event Object {type: 1, loaded: 2, total: 2} Download progress event Object {type: 3, loaded: 31, total: 31} Response Received... Object {description: "POST Response"}
angular、spring cloud 开源实战项目源码:https://gitee.com/xfdm/FCat
QQ群:549141844
代码持续更新…
相关文章推荐
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解
- 【Angular】angular-HttpClient 与服务器通讯 Get Post Put Delete Http 拦截器 请求讲解