React Native探索(五)使用fetch進(jìn)行網(wǎng)絡(luò)請(qǐng)求

前言

React Native可以使用多種方式來進(jìn)行網(wǎng)絡(luò)請(qǐng)求斧散,比如fetch、XMLHttpRequest以及基于它們封裝的框架诗力,fetch可以說是替代XMLHttpRequest的產(chǎn)物俱病,這一節(jié)我們就來學(xué)習(xí)fetch的基本用法粱甫。

1.get請(qǐng)求

fetch API是基于 Promise 設(shè)計(jì)的胜宇,因此了解Promise也是有必要的耀怜,推薦閱讀MDN Promise教程

get請(qǐng)求訪問淘寶IP庫

我們先從最基礎(chǔ)的get請(qǐng)求開始桐愉,get請(qǐng)求的地址為淘寶IP地址庫财破,里面有訪問接口的說明。請(qǐng)求代碼如下所示从诲。

 fetch('http://ip.taobao.com/service/getIpInfo.php?ip=59.108.51.32', {
             method: 'GET',
             headers: {
                'Content-Type': 'application/json'
            }
        }).then((response) => {//1
            console.log(response);
        }).catch((err) => {//2
            console.error(err);
        });

其中method用于定義請(qǐng)求的方法左痢,這里不用寫method也可以,fetch默認(rèn)的method就是GET。fetch方法會(huì)返回一個(gè)Promise對(duì)象俊性,這個(gè)Promise對(duì)象中包含了響應(yīng)數(shù)據(jù)response略步,也就是注釋1處的response參數(shù)。在注釋1處調(diào)用then方法將response打印在控制臺(tái)Console中定页,then方法同樣也會(huì)返回Promise對(duì)象纳像,Promise對(duì)象可以進(jìn)行鏈?zhǔn)秸{(diào)用,這樣就可以通過多次調(diào)用then方法對(duì)響應(yīng)數(shù)據(jù)進(jìn)行處理拯勉。在注釋2處通過catch方法來處理請(qǐng)求網(wǎng)絡(luò)錯(cuò)誤的情況。
除了上面這一種寫法憔购,我們還可以使用Request宫峦,如下所示。

let request = new Request('http://liuwangshu.cn', {
            method: 'GET',
            headers: ({
                    'Content-Type': 'application/json'
                 })
            });
        fetch(request).then((response) => {
            console.log(response);
        }).catch((err) => {
            console.error(err);
        });

我們先創(chuàng)建了Request對(duì)象玫鸟,并對(duì)它進(jìn)行設(shè)置导绷,最后交給fetch處理。
為了驗(yàn)證fetch的get請(qǐng)求屎飘,需要添加觸發(fā)get請(qǐng)求的代碼邏輯妥曲,如下所示。

import React, {Component} from 'react';
import {AppRegistry, View, Text, StyleSheet, TouchableHighlight} from 'react-native';
class Fetch extends Component {
    render() {
        return (
            <View style={styles.container}>
                <TouchableHighlight
                    underlayColor='rgb(210,260,260)'
                    style={{padding: 10, marginTop: 10, borderRadius: 5,}}
                    onPress={this.get}
                >
                    <Text >get請(qǐng)求</Text>
                </TouchableHighlight>
            </View>
        );
    }

    get() {
        fetch('http://ip.taobao.com/service/getIpInfo.php?ip=59.108.51.32', {
            method: 'GET',
        }).then((response) => {
            console.log(response);//1
        }).catch((err) => {//2
            console.error(err);
        });
    }
}
const styles = StyleSheet.create({
    container: {
        alignItems: 'center',
    }
});
AppRegistry.registerComponent('FetchSample', () => Fetch);

這里添加了一個(gè)TouchableHighlight钦购,并定義了它的點(diǎn)擊事件檐盟,一旦點(diǎn)擊就會(huì)觸發(fā)get方法請(qǐng)求網(wǎng)絡(luò)。運(yùn)行程序點(diǎn)擊“get請(qǐng)求”押桃,這時(shí)在控制臺(tái)Console中就會(huì)顯示回調(diào)的Response對(duì)象的數(shù)據(jù)葵萎,它包含了響應(yīng)狀態(tài)(status)、頭部信息(headers)唱凯、請(qǐng)求的url(url)羡忘、返回的數(shù)據(jù)等信息。這次請(qǐng)求的響應(yīng)狀態(tài)status為200磕昼,返回的數(shù)據(jù)是JSON格式的卷雕,用Charles抓包來查看返回的JSON,如下圖所示票从。


Response對(duì)象解析

Response對(duì)象中包含了多種屬性:

  • status (number) : HTTP請(qǐng)求的響應(yīng)狀態(tài)行漫雕。
  • statusText (String) : 服務(wù)器返回的狀態(tài)報(bào)告。
  • ok (boolean) :如果返回200表示請(qǐng)求成功纫骑,則為true蝎亚。
  • headers (Headers) : 返回頭部信息。
  • url (String) :請(qǐng)求的地址先馆。

Response對(duì)象還提供了多種方法:

  • formData():返回一個(gè)帶有FormData的Promise发框。
  • json() :返回一個(gè)帶有JSON對(duì)象的Promise。
  • text():返回一個(gè)帶有文本的Promise。
  • clone() :復(fù)制一份response梅惯。
  • error():返回一個(gè)與網(wǎng)絡(luò)相關(guān)的錯(cuò)誤宪拥。
  • redirect():返回了一個(gè)可以重定向至某URL的response。
  • arrayBuffer():返回一個(gè)帶有ArrayBuffer的Promise铣减。
  • blob() : 返回一個(gè)帶有Blob的Promise她君。

接下來對(duì)返回的Response進(jìn)行簡單的數(shù)據(jù)處理,如下所示葫哗。

   get() {
        fetch('http://ip.taobao.com/service/getIpInfo.php?ip=59.108.23.12', {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json'
            }
        }).then((response) => response.json())//1
            .then((jsonData) => {//2
                let country = jsonData.data.country;
                let city = jsonData.data.city;
                alert("country:" + country + "-------city:" + city);
            });
    }

訪問淘寶IP地址庫會(huì)返回JSON數(shù)據(jù)缔刹,因此在注釋1處調(diào)用response的json方法,將response轉(zhuǎn)換成一個(gè)帶有JSON對(duì)象的Promise劣针,也就是注釋2處的jsonData校镐。最后取出jsonData中數(shù)據(jù)并展示在Alert中,這里data是一個(gè)對(duì)象捺典,如果它是一個(gè)對(duì)象數(shù)組我們可以這樣獲取它的數(shù)據(jù):

 let country=jsonData.data[0].country;

點(diǎn)擊“get請(qǐng)求”鸟廓,效果如下所示。

2.post請(qǐng)求

post請(qǐng)求的代碼如下所示襟己。

   post() {
        fetch('http://ip.taobao.com/service/getIpInfo.php', {
            method: 'POST',//1
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({//2
                'ip': '59.108.23.12'
            })
        }).then((response) => response.json())
            .then((jsonData) => {
                let country = jsonData.data.country;
                let city = jsonData.data.city;
                alert("country:" + country + "-------city:" + city);
            });
    }

在注釋1處將method改為POST引谜,在注釋2處添加請(qǐng)求的body。與get請(qǐng)求類似擎浴,這里也添加一個(gè)觸發(fā)事件來進(jìn)行post請(qǐng)求员咽,當(dāng)點(diǎn)擊“post請(qǐng)求”時(shí),查看Charles抓包的請(qǐng)求的信息退客,如下圖所示骏融。

QQ圖片20170606135823.jpg

可以看到請(qǐng)求數(shù)據(jù)是一個(gè)GSON字符串,因?yàn)樘詫欼P庫并不支持此類型的POST請(qǐng)求萌狂,所以不會(huì)返回我們需要的地理信息數(shù)據(jù)档玻。

3.簡單封裝fetch

如果每次請(qǐng)求網(wǎng)絡(luò)都要設(shè)定method、headers茫藏、body等數(shù)據(jù)误趴,同時(shí)還要多次調(diào)用then方法對(duì)返回?cái)?shù)據(jù)進(jìn)行處理,顯然很麻煩务傲,下面就對(duì)上面例子中的get和post請(qǐng)求做一個(gè)簡單的封裝凉当。
首先創(chuàng)建一個(gè)FetchUtils.js,代碼如下所示售葡。

import React, {Component} from 'react';
class FetchUtils extends React.Component {
    static send(method, url, data, callback) {
        let request;
        if (method === 'get') {
            request = new Request(url, {
                method: 'GET',
                headers: ({
                    'Content-Type': 'application/json'
                })
            });
        } else if (method === 'post') {
            request = new Request(url, {
                method: 'POST',
                headers: ({
                    'Content-Type': 'application/json'
                }),
                body: JSON.stringify(data)
            });
        }
        fetch(request).then((response) => response.json())
            .then((jsonData) => {
                callback(jsonData);//1
            });
    }
}
module.exports = FetchUtils;

在FetchUtils中定義了send方法看杭,對(duì)GET和POST請(qǐng)求做了區(qū)分處理,并在注釋1處通過callback將響應(yīng)數(shù)據(jù)response回調(diào)給調(diào)用者挟伙。
最后調(diào)用FetchUtils的send方法楼雹,分別進(jìn)行GET和POST請(qǐng)求:

    let FetchUtils=require('./FetchUtils');
    ...
    sendGet() {
        FetchUtils.send('get', 'http://ip.taobao.com/service/getIpInfo.php?ip=59.108.23.16', '', 
        jsonData => {
            let country = jsonData.data.country;
            let city = jsonData.data.city;
            alert("country:" + country + "-------city:" + city);
        })
    }
    sendPost() {
        FetchUtils.send('post', 'http://ip.taobao.com/service/getIpInfo.php', {'ip': '59.108.23.16'}, 
        jsonData => {
            let country = jsonData.data.country;
            let city = jsonData.data.city;
            alert("country:" + country + "-------city:" + city);
        })
    }

這樣我們使用Fetch訪問網(wǎng)絡(luò)時(shí),只需要傳入需要的參數(shù),并對(duì)返回的jsonData 進(jìn)行處理就可以了贮缅。

github源碼

參考資料
Fetch API
fetch-issues-274
MDN Promise教程
ReactNative網(wǎng)絡(luò)fetch數(shù)據(jù)并展示在listview中
React Native中的網(wǎng)絡(luò)請(qǐng)求fetch和簡單封裝
在 JS 中使用 fetch 更加高效地進(jìn)行網(wǎng)絡(luò)請(qǐng)求
Using Fetch


歡迎關(guān)注我的微信公眾號(hào)榨咐,第一時(shí)間獲得博客更新提醒,以及更多成體系的Android相關(guān)原創(chuàng)技術(shù)干貨谴供。
掃一掃下方二維碼或者長按識(shí)別二維碼块茁,即可關(guān)注。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末桂肌,一起剝皮案震驚了整個(gè)濱河市数焊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌崎场,老刑警劉巖昌跌,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異照雁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)答恶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門饺蚊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悬嗓,你說我怎么就攤上這事污呼。” “怎么了包竹?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵燕酷,是天一觀的道長。 經(jīng)常有香客問我周瞎,道長苗缩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任声诸,我火速辦了婚禮酱讶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘彼乌。我一直安慰自己泻肯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布慰照。 她就那樣靜靜地躺著灶挟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪毒租。 梳的紋絲不亂的頭發(fā)上稚铣,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼榛泛。 笑死蝌蹂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的曹锨。 我是一名探鬼主播孤个,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沛简!你這毒婦竟也來了齐鲤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤椒楣,失蹤者是張志新(化名)和其女友劉穎给郊,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捧灰,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淆九,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了毛俏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炭庙。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖煌寇,靈堂內(nèi)的尸體忽然破棺而出焕蹄,到底是詐尸還是另有隱情,我是刑警寧澤阀溶,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布腻脏,位于F島的核電站,受9級(jí)特大地震影響银锻,放射性物質(zhì)發(fā)生泄漏永品。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一击纬、第九天 我趴在偏房一處隱蔽的房頂上張望腐碱。 院中可真熱鬧,春花似錦掉弛、人聲如沸症见。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谋作。三九已至,卻和暖如春乎芳,著一層夾襖步出監(jiān)牢的瞬間遵蚜,已是汗流浹背帖池。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吭净,地道東北人睡汹。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像寂殉,于是被迫代替她去往敵國和親囚巴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

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