通過HTTP或者HTTPS協定與網絡側伺服器交換資料是移動應用中常見的通信方式。 node-fetch是RN推薦的請求方式。
React Native架構在初始化項目時, 引入了node-fetch包 (因為npm3把依賴全部攤平了,node-fetch就在node_modules目錄下)
下面就是項目中引入的node-fetch的源碼:
聯網
聯網分為發送請求和接受響應兩步。分開來分析下。
發送請求
發送http/https gong細分一下共有6個步驟
1. 确定并準備請求位址與協定
2. 确定請求中的HTTP方法
3. 準備請求中藥傳輸的消息頭
4. 準備身份驗證資訊
5. 确定是否需要攜帶消息體/參數
6. 發出消息
我們以查詢号碼歸屬地這個位址示範下。
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
或者直接在xcode中打開ios項目進行配置。
接收響應
當請求成功,會傳回一個存儲有回應資料的對象
- type 字元串類型,記錄請求類型
- url 請求位址
- status 響應碼 200代表成功
- 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