fetch 取代 ajax、xmlHttpRequest的好東西

fetch是chrome 43版有的新功能

他是使用Promise去達成async的方法

可惜nodejs中沒有支援fetch必須安裝第三方node-fetch去達成fetch的使用

P.S. 目前我用的7.7.3版依然沒有內建,request老實說已經不想用了

另外最近覺得蠻感動的是chrome 57支援async/await原生啦,不過目前專案的瀏覽器受限於OS只能用43...OTL

就來簡單介紹一下它的功能吧

fetch說道能夠取代xhr和jquery的ajax大概是他的code捨棄了使用callback function這種噁心的東西

改成了目前處理同步/異步最方便的Promise語法

export default function fetch(urlstring | Requestinit?: RequestInit): Promise<Response>;

我直接拉node-fetch的定義檔說明

後面很明顯的return出來的是Promise的物件,解構之後會得出來是一個Response的東西。

一般對我來說最常用的大概就是POST和GET

所以使用方式就是

import fetch from 'node-fetch';

let a = async()=>{
    let data = await fetch('localhost://getData.com')
                        .then(res=>res.json());
}

如果用import * as fetch from 'node-fetch';

會出現

Cannot invoke an expression whose type lacks a call signature.

這行錯誤,就像我文中那樣進行宣告就好了

.then(res=>res.json())

這個階段的東西稱呼為body裡面含有一些相關的資訊,繼續來看定義檔(所以我說有定義檔真的對CODE理解幫助很大...沒有充分的文件只啃原始碼真的很痛苦)

export class Body {
    bodyUsedboolean;
    bodyNodeJS.ReadableStream;
    json(): Promise<any>;
    json<T>(): Promise<T>;
    text(): Promise<string>;
    buffer(): Promise<Buffer>;
}

export class Response extends Body {
    constructor(body?: BodyInitinit?: ResponseInit);
    static error(): Response;
    static redirect(urlstringstatusnumber): Response;
    typeResponseType;
    urlstring;
    statusnumber;
    okboolean;
    sizenumber;
    statusTextstring;
    timeoutnumber;
    headersHeaders;
    clone(): Response;
}

可以看到Response extends Body的屬性,所以將接下來要取出資料就是利用res.json()來將資料回傳出來變成我們想要的東西

那假若說要POST的話怎辦?

就是為他定義header和要傳送的資料,這一部分可以從RequestInit當中找起,當然對於其中某些定義可以再更詳細,見仁見智吧

interface RequestInit {
    //whatwg/fetch standard options
    method?: string;
    headers?: HeaderInit | { [indexstring]: string };
    body?: BodyInit;
    redirect?: RequestRedirect;

    //node-fetch extensions
    timeout?: number//=0 req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies)
    compress?: boolean//=true support gzip/deflate content encoding. false to disable
    size?: number//=0 maximum response body size in bytes. 0 to disable
    agent?: Agent//=null http.Agent instance, allows custom proxy, certificate etc.
    follow?: number//=20 maximum redirect count. 0 to not follow redirect

    //node-fetch does not support mode, cache or credentials options
}

OK  找到method的定義,body的定義,所以可以接下來寫POST檔案的傳輸方式

import fetch, { RequestInit } from 'node-fetch';

let a = async()=>{
    let header:RequestInit = {
        method: "POST",
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({a:1})
    }
    let data = await fetch('localhost://getData.com'header)
                        .then(res=>res.json());
}

其他東西我很少再用,或許以後處理影音、圖片部分才會有可能需要用到吧

基本上fetch常用方式就這樣,以上都是使用typescript撰寫應用在nodejs,若要使用在broser上應該大同小異。


留言

這個網誌中的熱門文章

Editor 比較~

ts-node 應用

n or nvm a nodejs version manager