angular2 學習筆記 ( Http 請求)

更新 : 2017-06-08 html

 

總以爲 angular 的 http 怎麼就多了 Request, Headers, Response 這些麻煩東東呢. android

原來這些都是遊覽器的「新特性」 Fetch API. 其實好久了,只是我不知道而已,哈哈。 git

Fetch API 和之前的 xmlhttprequest 主要功能是同樣的,就是發請求.github

不一樣的地方是Fetch 是基於 promise 的,並且能夠配合 service worker, stream, cache 之類的 "新特性" 打出連環計. web

它也是有不足的地方,好比沒辦法 abort 和 progress (不肯定目前有了沒有 /.\)typescript

有興趣的朋友能夠多留意這些 "新特性" 哦. json

 

 

refer : 後端

https://angular.cn/docs/ts/latest/guide/server-communication.htmlapi

https://xgrommx.github.io/rx-book/index.htmlpromise

http://wiki.jikexueyuan.com/project/android-weekly/issue-145/introduction-to-RP.html

 

概念上沒什麼太多的區別.

下面記入一些例子和小區別 : 

 

不一樣的地方 : 

1.不支持 ng1 的 interceptor 攔截和 transformations (要本身實現能夠試着繼承 http 服務來擴展)

2.默認結合rxjs (也能夠很容易的轉化回熟悉的 Promise)

 

提醒: 

1.XSRF 和 ng1 如出一轍 

2.ng 有一個內存 WebAPI 服務 ( in-memory web api service ),能夠模擬後端的 Web API 服務器. 不過我沒有用 ^^".

 

例子 :  

1.Headers and Params 

let headers = new Headers({ "myHeader": "myValue" });
headers.append("Accept", "application/json");
let params = new URLSearchParams();
params.set('myParam', 'myValue');
let options = new RequestOptions({ headers: headers, search: params });
this.http.get("/api/products", options).toPromise().then((response) => {
    console.log(response.json());
}); 

 

2.POST

let body = JSON.stringify({
    code : "mk200"
});
let headers = new Headers({ 'Content-Type': 'application/json' }); //其實不代表 json 也能夠, ng 默認好像是 json
let options = new RequestOptions({ headers: headers });
this.http.post("/api/products", body, options).toPromise().then((response) => {
    //do something...
});

 

3.get CSV 

let options = new RequestOptions({ responseType: ResponseContentType.Text });
this.http.get("/demo.csv", options).toPromise().then((response) => {
    console.log(response.text());             
}); 

 

4.by request 

let options = new RequestOptions({
    method: RequestMethod.Post,
    url: "/api/products",
    headers: new Headers({ 'Content-Type': 'application/json' }),
    body: JSON.stringify({ code: "mk200" })
});
this.http.request(new Request(options)).toPromise().then((response) => {
    //do something...
});

 

5. Upload file 

<input type="file" (change)="onFileChanged($event.target.files)" placeholder="Upload file" accept="image/*">
onFileChanged(fileList: FileList) {
    if (fileList.length > 0) {
        let file: File = fileList[0];
        let formData: FormData = new FormData();
        formData.append('uploadFile', file, file.name);            
        let headers = new Headers({ 
            "Accept": "application/json"
        });
        let options = new RequestOptions({ headers });
        this.http.post("https://localhost:44372/api/uploadFile", formData, options)
            .map(res => res.json())
            .catch(error => Observable.throw(error))
            .subscribe(
                data => console.log('success' + data),
                error => console.log(error)
            )
    }
}

ng 支持 formData, 關鍵就是別本身去寫 Content-Type header, ng 會幫咱們寫好的. 

 

攔截

不像 ng1 那樣,ng 並無給咱們一個攔截的接口, 不過咱們能夠經過簡單的繼承+override 來達到目的. 

refer : http://stackoverflow.com/questions/34934009/handling-401s-globally-with-angular-2

import { Injectable } from '@angular/core';
import { Http as NgHttp, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response } from "@angular/http";

import { Observable } from "rxjs/Observable";

@Injectable()
export class Http extends NgHttp {
    constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
        super(backend, defaultOptions);
    }
    get(url: string, options?: RequestOptionsArgs): Observable<Response>
    {
        console.log("in");
        return super.get(url,options);
    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {     
        console.log("in2");
        return super.request(url, options).catch((error: Response) => {
            console.log(error);           
            return Observable.throw(error);
        });
    }
}

get,post,put,delete 最終也是會調用 request 方法, 因此咱們能夠在 request 作大部分的攔截. 

typescript 中 override 父類方法不須要寫什麼 virtual, override 之類的, 直接寫方法就能夠了, 內部經過 super.method() 來調用父類方法, 不是 super() 哦.

咱們有 2 個選擇來調用這個 http, 第一就是聲明咱們的 service, 其二是覆蓋 ng 的 Http service.

import { Http as StoogesHttp } from "./http.service";
import { Http } from "@angular/http";

@NgModule({
    imports: [StoogesModule, DebugRoutingModule],
    exports: [],
    declarations: [DebugComponent],
    providers: [{ provide : Http, useClass : StoogesHttp }] //這樣就覆蓋掉了. 能夠參考我寫的 angular2 依賴注入
})
export class DebugModule { 
  
}
相關文章
相關標籤/搜索