本身常常用的方式:json
Angular2的http訪問常常採用兩種方式:bootstrap
共同點:導入相應的Module後端
import {Http, RequestOptions, Response} from '@angular/http';
在module文件中配置api
import {HttpModule} from '@angular/http';
imports: [ // import Angular's modules
BrowserModule, BrowserAnimationsModule, HttpModule,
在service的構造器中進行注入promise
constructor(private http: Http) { super(); }
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裏面能夠本身自定義,以後控制層調用服務層angular2
1 /*獲取經營單位數據*/
2 public getUnitInfo() { 3 this.parkManageService.getUnitInfo().then(data => { 4 this.units = data.unit; 5 }); 6 }
1.2 用Observable實現服務層app
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 }
控制層調用async
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:HttpClientModuleide
導入新的 HTTP Modulepost
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()
APIconst params = new HttpParams({fromString: 'orderBy="$key"&limitToFirst=1'}); this.courses$ = this.http .request( "GET", "/courses.json", { responseType:"json", params }) .subscribe(data => _.values(data));
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));
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 }
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 }
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 }
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 }
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 }
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...
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 { }
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"}