AngularX Http服务总结

自己经常用的方式:

1.首先看httpModule

  Angular2的http访问经常采用两种方式:

  共同点:导入相应的Module

import {Http, RequestOptions, Response} from '@angular/http';

  在module文件中配置

import {HttpModule} from '@angular/http';
imports: [ // import Angular's modules
    BrowserModule,
    BrowserAnimationsModule,
    HttpModule,

  在service的构造器中进行注入

constructor(private http: Http) {
    super();
  }

1.1 用promise实现服务层返回

1  // 获取设置
2   public getOptions(): Promise<any> {
3     return this.http
4       .get(this._optionApiUrl)
5       .toPromise()
6       .then((res: Response) => res.json())
7       .catch((error: any) => Observable.throw(error || 'Server error'));
8   }

其中then里面、catch里面可以自己自定义,之后控制层调用服务层

1 /*获取经营单位数据*/
2   public getUnitInfo() {
3     this.parkManageService.getUnitInfo().then(data => {
4       this.units = data.unit;
5     });
6   }

1.2 用Observable实现服务层

1 /*根据查询条件获取数据*/
2   public getParkInfoByParams(jsonObject: any): Observable<any> {
3     return this.http.request(this.getParkInfoByParamUrl, new RequestOptions({ method: 'GET', body: jsonObject }))
4       .map((res: Response) => res.json())
5       .catch((error: any) => Observable.throw(error || 'Server error'));
6   }

控制层调用

 1  /*请求后台数据*/
 2   public getSuggests(pageNum: number) {
 3     this.suggestService.getSuggestInfo(`/Bi/${ConstantValue.CHECKCODE}/querySuggest/${pageNum}/${this.pageSize}`,
 4       this.getSearchParams())
 5       .subscribe(
 6         data => {
 7           // console.log(data);
 8           ...............
 9         },
10         error => console.log('errorMsg:请求建议信息失败...')
11       );
12   }

 

2.Angular4 推出了一个新的http请求module:HttpClientModule

导入新的 HTTP Module

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

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

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

现在我们可以这样写:

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

发送get请求

1 public saveUser2() {
2     let url = "http://localhost:8080/financial/user/getUsers/2";
3     this.httpClient
4     .get(url)
5     .subscribe(data => {
6       console.log(data)
7     });
8   }

带参数请求(REST方式请求不建议这样使用参数)

 1 import {HttpParams} from "@angular/common/http";
 2 
 3 const params = new HttpParams()
 4     .set('orderBy', '"$key"')
 5     .set('limitToFirst', "1");
 6 
 7 this.courses$ = this.http
 8     .get("/courses.json", {params})9     .subscribe(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
        })
    .subscribe(data => _.values(data));

设置 HTTP Headers

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

发送 Put 请求

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

发送 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",  val);
 6             },
 7             response => {
 8                 console.log("DELETE call in error", response);
 9             },
10             () => {
11                 console.log("The DELETE observable is now completed.");
12             });
13 }

发送 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",  val);
13             },
14             response => {
15                 console.log("POST call in error", response);
16             },
17             () => {
18                 console.log("The POST observable is now completed.");
19             });
20 }

避免重复请求

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

  在上面例子中,我们正在创建了一个 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 操作符:

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

顺序发送 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         
8     sequence$.subscribe();
9 }

获取顺序发送 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 
 9     sequence$.subscribe(values => console.log("result observable ", values) );
10 }

请求异常处理

 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 
 9             return Observable.of({description: "Error Value Emitted"});
10         })
11         .subscribe(
12             val => console.log('Value emitted successfully', val),
13             error => {
14                 console.error("This line is never called ",error);
15             },
16             () => console.log("HTTP Observable completed...")
17         );
18 }

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

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 拦截器

定义拦截器

 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 
 6 @Injectable()
 7 export class AuthInterceptor implements HttpInterceptor {
 8     
 9     constructor(private authService: AuthService) {
10     }
11 
12     intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
13         const clonedRequest = req.clone({
14             headers: req.headers.set('X-CustomAuthHeader', authService.getToken())
15         });
16         console.log("new headers", clonedRequest.headers.keys());
17         return next.handle(clonedRequest);
18     }
19 }

配置拦截器

 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 
 6     this.http.request(request)
 7         .subscribe(
 8             event => {
 9                 if (event.type === HttpEventType.DownloadProgress) {
10                     console.log("Download progress event", event);
11                 }
12                 if (event.type === HttpEventType.UploadProgress) {
13                     console.log("Upload progress event", event);
14                 }
15                 if (event.type === HttpEventType.Response) {
16                     console.log("response received...", event.body);
17                 }
18             }
19         );
20 }

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

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"}
posted @ 2017-10-25 15:31  一頁書  阅读(307)  评论(0编辑  收藏  举报