天天看點

react-native 網絡請求fetch

前言:

官方推薦是網絡請求Fetch 今天記錄下這個Fetch
           

片段一:不同

Ajax  JQuery-Ajax  axios fetch差別: 

傳統 Ajax   指的是 XMLHttpRequest(XHR)最早出現的發送後端請求技術,隸屬于原始js中,核心使用XMLHttpRequest對象

JQuery-Ajax  是對原生XHR的封裝,除此以外還增添了對JSONP的支援

axios  從浏覽器中建立XMLHttpRequest  從node層發起http請求  支援 Promise API 
自動轉json 用戶端支援防止CSRF(因為從cookie裡面擷取key值後發送到服務端會檢測).提供了一些并發請求的接口

Fetch  是基于promise設計的   脫離了XHR 
符合關注分離,沒有将輸入、輸出和用事件來跟蹤的狀态混雜在一個對象裡  .更好更友善的寫法 
           

片段二:缺點

fetch隻對網絡請求報錯,對400,500都當做成功的請求,伺服器傳回 400,500 錯誤碼時并不會 reject,隻有網絡錯誤這些導緻
請求不能完成時才會被 reject。
fetch預設不會帶cookie,需要添加配置項: fetch(url, {credentials: 'include'})
fetch沒有辦法原生監測請求的進度,而XHR可以
           

片段三:真實的fetch

fetch 是一個 low-level 的 API,它注定不會像你習慣的 $.ajax 或是 axios 等庫幫你封裝各種各樣的功能或實作。
也正是因為這個定位,在學習或使用 fetch API 時,你會遇到不少的挫折。
           

片段四:請求比你想象的要複雜

這是我對fetch的第一眼認識:
fetch('http://abc.com/tiger.png');
預設是get方法的form-data(也就是headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'})
原來需要 new XMLHttpRequest 等小十行代碼才能實作的功能如今一行代碼就能搞定,着實讓人心動!
很可能會得到一個 401 Unauthorized 的結果,為什麼?
會發現原來 fetch 在發送請求時預設不會帶上 Cookie!
你需要:
fetch('/api/add?name=lucy', {
  credentials: 'include',
  ...
});
理,如果你需要 POST 一個 JSON 到服務端,你需要這樣做:
fetch('/api/add', {  
  method: 'POST',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  },
  body: JSON.stringify({name: 'lucy'})
});
           

片段五 錯誤處理,比你想象的複雜

按照 MDN 的說法,fetch 隻有在遇到網絡錯誤的時候才會 reject 這個 promise,比如使用者斷網或請求位址的域名無法解析等。
是以隻要伺服器能夠傳回 HTTP 響應(甚至隻是 CORS preflight 的 OPTIONS 響應),promise 一定是 resolved 的狀态。
你的404,513,502等一律通過。這個就尴尬了。

判斷一個 fetch 請求是不是成功呢?你得用 response.ok 這個字段。
fetch('xx.png')  
.then((response) => {
  if (response.ok) {
    console.log('ok');
  } else {
    thorw new error('network error');
  }
})
.catch(() => {
  console.log('error');
});
對資料格式處理 
fetch('/api/user.json?id=2')   // 服務端傳回 {"name": "test", "age": 1} 字元串  
.then((response) => {
  // 這裡拿到的 response 并不是一個 {name: 'test', age: 1} 對象
  return response.json();  // 将 response.body 通過 JSON.parse 轉換為 JS 對象
})
.then(data => {
  console.log(data); // {name: 'test', age: 1}
});
           

啰嗦一句:

fetch 不支援同步請求   fetch不支援取消一個請求(使用 XMLHttpRequest 你可以用 

xhr.abort()

 方法取消一個請求)    fetch 無法檢視請求的進度(使用 XMLHttpRequest 你可以通過 

xhr.onprogress

 回調來動态更新請求的進度)

繼續閱讀