React Native探索(五)使用fetch進行網絡請求

相關文章
React Native探索系列php

前言

React Native可使用多種方式來進行網絡請求,好比fetch、XMLHttpRequest以及基於它們封裝的框架,fetch能夠說是替代XMLHttpRequest的產物,這一節咱們就來學習fetch的基本用法。html

1.get請求

fetch API是基於 Promise 設計的,所以瞭解Promise也是有必要的,推薦閱讀MDN Promise教程node

get請求訪問淘寶IP庫

咱們先從最基礎的get請求開始,get請求的地址爲淘寶IP地址庫,裏面有訪問接口的說明。請求代碼以下所示。react

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用於定義請求的方法,這裏不用寫method也能夠,fetch默認的method就是GET。fetch方法會返回一個Promise對象,這個Promise對象中包含了響應數據response,也就是註釋1處的response參數。在註釋1處調用then方法將response打印在控制檯Console中,then方法一樣也會返回Promise對象,Promise對象能夠進行鏈式調用,這樣就能夠經過屢次調用then方法對響應數據進行處理。在註釋2處經過catch方法來處理請求網絡錯誤的狀況。
除了上面這一種寫法,咱們還可使用Request,以下所示。git

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);
        });複製代碼

咱們先建立了Request對象,並對它進行設置,最後交給fetch處理。
爲了驗證fetch的get請求,須要添加觸發get請求的代碼邏輯,以下所示。github

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請求</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);複製代碼

這裏添加了一個TouchableHighlight,並定義了它的點擊事件,一旦點擊就會觸發get方法請求網絡。運行程序點擊「get請求」,這時在控制檯Console中就會顯示回調的Response對象的數據,它包含了響應狀態(status)、頭部信息(headers)、請求的url(url)、返回的數據等信息。此次請求的響應狀態status爲200,返回的數據是JSON格式的,用Charles抓包來查看返回的JSON,以下圖所示。
json

Response對象解析

Response對象中包含了多種屬性:react-native

  • status (number) : HTTP請求的響應狀態行。
  • statusText (String) : 服務器返回的狀態報告。
  • ok (boolean) :若是返回200表示請求成功,則爲true。
  • headers (Headers) : 返回頭部信息。
  • url (String) :請求的地址。

Response對象還提供了多種方法:數組

  • formData():返回一個帶有FormData的Promise。
  • json() :返回一個帶有JSON對象的Promise。
  • text():返回一個帶有文本的Promise。
  • clone() :複製一份response。
  • error():返回一個與網絡相關的錯誤。
  • redirect():返回了一個能夠重定向至某URL的response。
  • arrayBuffer():返回一個帶有ArrayBuffer的Promise。
  • blob() : 返回一個帶有Blob的Promise。

接下來對返回的Response進行簡單的數據處理,以下所示。服務器

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地址庫會返回JSON數據,所以在註釋1處調用response的json方法,將response轉換成一個帶有JSON對象的Promise,也就是註釋2處的jsonData。最後取出jsonData中數據並展現在Alert中,這裏data是一個對象,若是它是一個對象數組咱們能夠這樣獲取它的數據:

let country=jsonData.data[0].country;複製代碼

點擊「get請求」,效果以下所示。

2.post請求

post請求的代碼以下所示。

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處添加請求的body。與get請求相似,這裏也添加一個觸發事件來進行post請求,當點擊「post請求」時,查看Charles抓包的請求的信息,以下圖所示。

QQ圖片20170606135823.jpg

能夠看到請求數據是一個GSON字符串,由於淘寶IP庫並不支持此類型的POST請求,因此不會返回咱們須要的地理信息數據。

3.簡單封裝fetch

若是每次請求網絡都要設定method、headers、body等數據,同時還要屢次調用then方法對返回數據進行處理,顯然很麻煩,下面就對上面例子中的get和post請求作一個簡單的封裝。
首先建立一個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方法,對GET和POST請求作了區分處理,並在註釋1處經過callback將響應數據response回調給調用者。
最後調用FetchUtils的send方法,分別進行GET和POST請求:

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訪問網絡時,只須要傳入須要的參數,並對返回的jsonData 進行處理就能夠了。

github源碼

參考資料
Fetch API
fetch-issues-274
MDN Promise教程
ReactNative網絡fetch數據並展現在listview中
React Native中的網絡請求fetch和簡單封裝
在 JS 中使用 fetch 更加高效地進行網絡請求
Using Fetch


歡迎關注個人微信公衆號,第一時間得到博客更新提醒,以及更多成體系的Android相關原創技術乾貨。
掃一掃下方二維碼或者長按識別二維碼,便可關注。

相關文章
相關標籤/搜索