天天看點

從零學React Native之14 網絡請求聯網完整的例子

通過HTTP或者HTTPS協定與網絡側伺服器交換資料是移動應用中常見的通信方式。 node-fetch是RN推薦的請求方式。

React Native架構在初始化項目時, 引入了node-fetch包 (因為npm3把依賴全部攤平了,node-fetch就在node_modules目錄下)

下面就是項目中引入的node-fetch的源碼:

從零學React Native之14 網絡請求聯網完整的例子

聯網

聯網分為發送請求和接受響應兩步。分開來分析下。

發送請求

發送http/https gong細分一下共有6個步驟

1. 确定并準備請求位址與協定

2. 确定請求中的HTTP方法

3. 準備請求中藥傳輸的消息頭

4. 準備身份驗證資訊

5. 确定是否需要攜帶消息體/參數

6. 發出消息

我們以查詢号碼歸屬地這個位址示範下。

從零學React Native之14 網絡請求聯網完整的例子

1. 确定并準備請求位址與協定

請求位址以http/https 開頭,為了便于修改位址,通常将位址放在一個變量中。IOS9以上預設無法通路http請求, 具體參考後面的注意事項。

let url=`http://apis.baidu.com/showapi_open_bus/mobile/find`;
           

2. 确定請求中的HTTP方法

根據HTTP協定的設計初衷,不同的方法對資源有不同的操作方式:

+ PUT :增

+ DELETE :删

+ POST:改

+ GET:查

最常用的是GET和POST(實際上GET和POST都能辦到增删改查)

如果不指定,預設的方法為GET,目前使用的api接口隻支援get請求

let map={
     method:'GET'
};
           

3. 準備請求中藥傳輸的消息頭

接下來需要設定請求中需要傳輸的消息頭。消息頭分為兩種,其中一種是協定規定的标準消息頭;另一種是使用者自定義的消息頭。

let privateHeaders={
     'Private-Header':'values1', //自定義消息頭
     //'Content-Type':"text/plain", //設定消息體格式,GET請求不需要設定
     //'User-Agent':'testAgent',// 如果不設定預設為okhttp/2.5.0
     'apikey':'9dc7ab2f8993b0b215ad8c550e1f4ebe' //百度賬号的apikey
};
map.headers=privateHeaders; //加上自定義消息頭
map.follow=;//設定允許最大的重定向次數,0不允許重定向
map.timeout=;//設定逾時時間,0代表沒有
map.size=;//請求回應中消息體最大允許的長度,0沒有限制
           

RN支援gzip/deflate格式編碼,不需要對此進行設定。RN收到gzip/deflate格式編碼會自動轉換為普通格式交給開發者。

消息頭是不區分大小寫的,如果有大寫字母,傳輸的時候回自動轉換為小寫。

key資訊請自己注冊。

4. 準備身份驗證資訊

某些Http請求需要加入身份驗證資訊,比如上面的apikey,有些時候在需要進行身份驗證的時候需要兩次HTTP請求來完成。

5. 确定是否需要攜帶消息體/參數

如果需要帶消息體,可以通過body配置,GET請求不需要。

map.body=JSON.stringify({
       fistParam:'yourValue',
       secondParam:'yourValue'
});
           

POST請求參數是放在消息體中,而GET直接拼裝在請求位址後面通過?間隔。

let url=`http://apis.baidu.com/showapi_open_bus/mobile/find`;
let params='num=13126939916';
let requestURL=url+"?"+params;
           

6. 發出消息

将上述5步聯合起來就可以得到發送HTTP或HTTPS的請求片段。如下:

componentDidMount() {
        let url=`http://apis.baidu.com/showapi_open_bus/mobile/find`;
        let params='num=13126939916';
        let requestURL=url+"?"+params;
        let map={
          method:'GET'
        };
        let privateHeaders={
          //  'Private-Header':'values1', //自定義消息頭
          //  'Content-Type':"text/plain", //設定消息體格式,GET請求不需要設定
          //  'User-Agent':'testAgent',// 如果不設定預設為okhttp/2.5.0
            'apikey':'9dc7ab2f8993b0b215ad8c550e1f4ebe'
        };
         map.headers=privateHeaders; //加上自定義消息頭
         map.follow=;//設定允許最大的重定向次數,0不允許重定向
         map.timeout=;//設定逾時時間,0代表沒有
         map.size=;//請求回應中消息體最大允許的長度,0沒有限制
         //map.body='this is body';
        fetch(requestURL,map)
            .then(
                (result)=>{
                    //接受回應消息處理.
                    console.log(result);
                }
            )
    }
           

注意事項 解決IOS9以上預設不能通路http請求

WWDC 15 提出的 ATS (App Transport Security) 是 Apple 在推進網絡通訊安全的一個重要方式。在 iOS 9 和 OS X 10.11 中,預設情況下非 HTTPS 的網絡通路是被禁止的。當然,因為這樣的推進影響面非常廣,作為緩沖,我們可以在 Info.plist 中添加 NSAppTransportSecurity 字典并且将NSAllowsArbitraryLoads 設定為 YES 來禁用 ATS。

找到info.plist檔案添加NSAllowsArbitraryLoads

從零學React Native之14 網絡請求聯網完整的例子
從零學React Native之14 網絡請求聯網完整的例子

或者直接在xcode中打開ios項目進行配置。

從零學React Native之14 網絡請求聯網完整的例子

接收響應

當請求成功,會傳回一個存儲有回應資料的對象

從零學React Native之14 網絡請求聯網完整的例子
  1. type 字元串類型,記錄請求類型
  2. url 請求位址
  3. status 響應碼 200代表成功
  4. ok 布爾類型,記錄是否成功。

fetch方法

fetch 傳回的 then 方法有一個 response 參數,它是一個 Response 執行個體。 Response 有如下方法:

  • clone() - 複制一份response
  • error() - 傳回一個與網絡相關的錯誤
  • redirect() - 傳回了一個可以重定向至某URL的response.
  • arrayBuffer() - 傳回一個帶有ArrayBuffer的Promise.
  • blob() - 傳回一個帶有Blob的Promise.
  • formData() - 傳回一個帶有FormData的Promise.
  • json() - 傳回一個帶有JSON格式對象的Promise.
  • text() - 傳回一個帶有文本的Promise.

下面就是完整的傳回json的例子:

fetch(requestURL,map)
     .then((result)=>result.json()) // 傳回帶有json格式的Promise
     .catch((error)=>{   // 捕獲錯誤
           console.log(error);  
     })
     .then((responseData)=>{   // 輸出json資料
           console.log(responseData);
     });
           

完整的例子

componentDidMount() {
        let url=`http://apis.baidu.com/showapi_open_bus/mobile/find`;
        let params='num=13126939916';
        let requestURL=url+"?"+params;
        let map={
          method:'GET'
        };
        let privateHeaders={
            'apikey':'9dc7ab2f8993b0b215ad8c550e1f4ebe'
        };
         map.headers=privateHeaders; //加上自定義消息頭
         map.follow=;//設定允許最大的重定向次數,不允許重定向
         map.timeout=;//設定逾時時間,代表沒有
         map.size=;//請求回應中消息體最大允許的長度,沒有限制
        fetch(requestURL,map)
            .then((result)=>result.json()) //.json()
            .catch((error)=>{
                console.log(error);
            })
            .then((responseData)=>{
                console.log(responseData);
            });
    }
           

當然也可以用ES2017的文法:

async netWork() {
        let url=`http://apis.baidu.com/showapi_open_bus/mobile/find`;
        let params='num=13126939916';
        let requestURL=url+"?"+params;
        try {
            let response = await fetch(requestURL,{
                headers:{
                    'apikey':'9dc7ab2f8993b0b215ad8c550e1f4ebe'
                }
            });
            let responseJson = await response.json();
            console.log(responseJson);
            return responseJson;
        } catch (error) {
            console.error(error);
        }
    }
           

更多精彩請關注微信公衆賬号likeDev

從零學React Native之14 網絡請求聯網完整的例子