React Native Fetch封裝那點事...

每一門語言都離不開網(wǎng)絡(luò)請求财边,有自己的一套Networking Api围苫。React Native使用的是Fetch俄精。 今天我們來談?wù)勁cFetch相關(guān)的一些事情刁笙。

purpose

通過這篇文章,你將了解到以下幾點關(guān)于Fetch的獨家報道

  • Fetch的簡單運用
  • Fetch的主要Api
  • Fetch使用注意事項
  • Fetch的Promise封裝

fetch

fetch的使用非常簡單滋尉,只需傳入請求的url

fetch('https://facebook.github.io/react-native/movies.json');

當(dāng)然是否請求成功與數(shù)據(jù)的處理玉控,我們還需處理成功與失敗的回調(diào)

function getMoviesFromApiAsync() {
  return fetch('https://facebook.github.io/react-native/movies.json')
    .then((response) => response.json())
    .then((responseJson) => {
      return responseJson.movies;
    })
    .catch((error) => {
      console.error(error);
    });
}

通過response.json()將請求的返回數(shù)據(jù)轉(zhuǎn)化成json數(shù)據(jù)以便使用。通過.then來對數(shù)據(jù)進行轉(zhuǎn)化處理或最終暴露給調(diào)用者狮惜;.catch對異常的處理高诺。

以上就是一個簡單的網(wǎng)絡(luò)請求,該請求默認是get方式碾篡。那么post又該如何請求呢厢蒜?

Api & Note

在fetch中我們直接傳入url進行請求民假,其實內(nèi)部本質(zhì)是使用了Request對象鸿秆,只是將url出入到了Request對象中口四。

const myRequest = new Request('https://facebook.github.io/react-native/movies.json');
 
const myURL = myRequest.url; // https://facebook.github.io/react-native/movies.jsonflowers.jpg
const myMethod = myRequest.method; // GET
 
fetch(myRequest)
  .then(response => response.json())
  .then(responseJson => {
    //todo
  });

如果我們需要請求post,需要改變Request的method屬性穆律。

fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    firstParam: 'yourValue',
    secondParam: 'yourOtherValue',
  }),
});

非常簡單惠呼,在url后直接傳入{}對象,其中指定method使用post峦耘。

相信大家應(yīng)該都知道get與post的一個主要區(qū)別是get可以在url上直接添加參數(shù)剔蹋,而post為了安全都不采用直接將參數(shù)追加到url上,而是使用body來傳給service端贡歧。

在使用body前滩租,這里還需知道headers。下面某個post請求的headers信息

需要注意的是Content-Type字段利朵,它代表的是service端接收的數(shù)據(jù)類型,圖片中使用的是application/x-www-form-urlencoded猎莲。這對于我們的body來說是非常重要的绍弟。只有匹配Content-Type的類型才能正確的傳遞參數(shù)信息。

示例的代碼使用的是application/json著洼,所以body使用Json.stringify()進行參數(shù)轉(zhuǎn)換樟遣,而對于Content-Type為application/x-www-form-urlencoded,需要使用queryString.stringify()身笤。

Request中除了method豹悬、headers與body,還有以下屬性

  • Request.cache: 請求的緩存模式(default/reload/no-cache)
  • Request.context: 請求的上下文(audio/image/iframe)
  • Request.credentials: 請求的證書(omit/same-origin/include)
  • Request.destination: 請求的內(nèi)容描述類型
  • Request.integrity: 請求的 subresource integrity
  • Request.mode: 請求的模式(cors/no-cors/same-origin/navigate)
  • Request.redirect: 請求的重定向方式(follow/error/manual)
  • Request.referrer: 請求的來源(client)
  • Request.referrerPolicy: 請求的來源政策(no-referrer)
  • Request.bodyUsed: 聲明body是否使用在response中

請求成功之后液荸,使用.then來轉(zhuǎn)換數(shù)據(jù)瞻佛,使用最多的是Body.json(),當(dāng)然你也可以使用以下的幾種數(shù)據(jù)轉(zhuǎn)換類型

  • Body.arrayBuffer
  • Body.blob
  • Body.formData
  • Body.text

以上是fetch請求相關(guān)的屬性與方法。如果你已經(jīng)有所了解伤柄,那么恭喜你對fetch的基本使用已經(jīng)過關(guān)了绊困,下面對fetch的使用進行封裝。

封裝

在實際開發(fā)中适刀,url的host都是相同的秤朗,不同的是請求的方法名與參數(shù)。而對于不同的環(huán)境(debug|release)請求的方式也可能不同笔喉。例如:在debug環(huán)境中為了方便調(diào)試查看請求的參數(shù)是否正確取视,我們會使用get來進行請求。所以在封裝之前要明確什么是不變的常挚,什么是變化的作谭,成功與失敗的響應(yīng)處理。

經(jīng)過上面的分析待侵,羅列一下封裝需要做的事情丢早。

  • 不變的: host,headers,body.json()
  • 變化的: url,method,body
  • 響應(yīng)方式: Promise(resolve/reject)
function convertUrl(url, params) {
    let realUrl = ApiModule.isDebug?
        url + "?" + queryString.stringify(Object.assign({}, params, commonParams)) : url;

    if (ApiModule.isDebug) {
        console.log("request: " + realUrl);
    }
    return realUrl;
}

首先對url與參數(shù)params進行拼接,如果為debug模式將params拼接到url后秧倾。這里使用到了Object.assign()將params與commonParams組合成一個{}對象怨酝。最終通過queryString.stringify轉(zhuǎn)化成string。

ApiModule.isDebug是原生傳遞過來的值那先,對于Android/IOS只需傳遞自己的ApiModule即可农猬。

function getMethod() {
    return ApiModule.isDebug? "get": "post";
}

上述提到的get與post的請求時機。

const headers = {
    Accept: 'application/json',
    "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
};

在headers中Content-Type類型為application/x-www-form-urlencode

function convertBody(params) {
    return ApiModule.isDebug? undefined : queryString.stringify(Object.assign({}, params, commonParams));
}

由于debug模式使用的是get方式售淡,但get規(guī)定是不能有body的斤葱,所以這里使用了undefined來標(biāo)識。同時為了匹配headers中的Content-Type揖闸,params的轉(zhuǎn)化必須使用queryString.stringify揍堕;如果接受的是json,可以使用JSON.stringify。

定義完之后fetch對外只需接受params參數(shù)即可汤纸。

async function fetchRequest(params){
    let body = convertBody(params);
    fetch(convertUrl(baseUrl, params),{
        method: method,
        headers: headers,
        body: body
    })
    .then((response) => response.json())
    .then((responseJson) => {
        //todo success
    })
    .catch((error) => {
        if (ApiModule.isDebug) {
            console.error("request error: " + error);
        };
        //todo error
    });
}

fetch的請求封裝完成衩茸,但我們的成功與失敗的狀態(tài)并沒有通知給調(diào)用者,所以還需要一個回調(diào)機制贮泞。Promise是一個異步操作最終完成或者失敗的對象楞慈。它可以接受兩個函數(shù)resolve、reject

const p = new Promise((resolve, reject){
    ...
    //success
    resolve('success')
    //error
    reject('error')
});
//use
p.then(success => {
        console.log(success);
    }, error => {
        console.log(error)  
});

將fetch請求放入到Promise的異步操作中啃擦,這樣一旦數(shù)據(jù)成功返回就調(diào)用resolve函數(shù)回調(diào)給調(diào)用者囊蓝;失敗調(diào)用reject函數(shù),返回失敗信息令蛉。而調(diào)用者只需使用Promise的.then方法等候數(shù)據(jù)的回調(diào)通知聚霜。下面來看下完整的fetch封裝。

async function fetchRequest(params){
    let body = convertBody(params);
    return new Promise(function(resolve, reject){
        fetch(convertUrl(baseUrl, params),{
            method: method,
            headers: headers,
            body: body
        })
        .then((response) => response.json())
        .then((responseJson) => {
            resolve(responseJson);
        })
        .catch((error) => {
            if (ApiModule.isDebug) {
                console.error("request error: " + error);
            };
            reject(error);
        });
    });
}

之后對fetch的使用就非常簡單了,只需傳入需要的參數(shù)即可俯萎。

fetchRequest({method: "goods.getInfo", goodsId: 27021599158370074})
.then(res =>{
    this.setState({
        shareInfo: res.data.shareInfo
    });
});

以上是有關(guān)fetch的全部內(nèi)容傲宜,當(dāng)然在React Native中還有其它的第三方請求庫:XMLHttpRequest,同時也支持WebSockets夫啊。感興趣的也可以去了解一下函卒,相信會有不錯的收獲。

精選文章

5分鐘吃透React Native Flexbox
ViewDragHelper之手勢操作神器
自定義Android注解Part2:代碼自動生成
Bitmap的圖片壓縮匯總

拉粉環(huán)節(jié):感覺不錯的可以來一波關(guān)注撇眯,掃描下方二維碼报嵌,關(guān)注公眾號,及時獲取最新知識技巧熊榛。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锚国,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子玄坦,更是在濱河造成了極大的恐慌血筑,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件煎楣,死亡現(xiàn)場離奇詭異豺总,居然都是意外死亡,警方通過查閱死者的電腦和手機择懂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門喻喳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人困曙,你說我怎么就攤上這事表伦。” “怎么了慷丽?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵蹦哼,是天一觀的道長。 經(jīng)常有香客問我要糊,道長翔怎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任杨耙,我火速辦了婚禮,結(jié)果婚禮上飘痛,老公的妹妹穿的比我還像新娘珊膜。我一直安慰自己,他們只是感情好宣脉,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布车柠。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪竹祷。 梳的紋絲不亂的頭發(fā)上谈跛,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天,我揣著相機與錄音塑陵,去河邊找鬼感憾。 笑死,一個胖子當(dāng)著我的面吹牛令花,可吹牛的內(nèi)容都是我干的阻桅。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼兼都,長吁一口氣:“原來是場噩夢啊……” “哼嫂沉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起扮碧,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤趟章,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后慎王,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚓土,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年柬祠,在試婚紗的時候發(fā)現(xiàn)自己被綠了北戏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡漫蛔,死狀恐怖嗜愈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情莽龟,我是刑警寧澤蠕嫁,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站毯盈,受9級特大地震影響剃毒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜搂赋,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一赘阀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脑奠,春花似錦基公、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胰伍。三九已至,卻和暖如春酸休,著一層夾襖步出監(jiān)牢的瞬間骂租,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工斑司, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留渗饮,地道東北人。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓陡厘,卻偏偏與公主長得像抽米,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子糙置,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容