天天看點

[轉] 學會fetch的用法

fetch是web提供的一個可以擷取異步資源的api,目前還沒有被所有浏覽器支援,它提供的api傳回的是Promise對象,是以你在了解這個api前首先得了解Promise的用法。參考阮老師的文章

那我們首先講講在沒有fetch的時候,我們是如何擷取異步資源的:

//發送一個get請求是這樣的:

//首先執行個體化一個XMLHttpRequest對象
var httpRequest = new XMLHttpRequest();

//注冊httpRequest.readyState改變時會回調的函數,httpRequest.
//readyState共有5個可能的值,
//0	UNSENT (未打開)	open()方法還未被調用;
//1	OPENED  (未發送)	send()方法還未被調用;
//2	HEADERS_RECEIVED (已擷取響應頭)	send()方法已經被調用, 響應頭和響應狀态已經傳回;
//3	LOADING (正在下載下傳響應體)	響應體下載下傳中; responseText中已經擷取了部分資料;
//4	DONE (請求完成)	整個請求過程已經完畢.
httpRequest.onreadystatechange = function(){
 //該回調函數會被依次調用4次
 console.log(httpRequest.readyState);

 if(httpRequest.readyState===4){
   //請求已完成
   if(httpRequest.status===200){
     //http狀态為200
     console.log(httpRequest.response);

     var data = JSON.parse(httpRequest.response);
     console.log(data);
   }
 }

}

//請求的網址
var url = "http://127.0.0.1:7777/list";
//該方法為初始化請求,第一個參數是請求的方法,比如GET,POST,PUT,第二個參數是請求的url
httpRequest.open('GET',url,true);

//設定http請求頭
httpRequest.setRequestHeader("Content-Type","application/json");

//送出請求,參數為要發送的body體,如果是GET方法的話,一般無需發送body,設為空就可以
httpRequest.send(null);

           

關于XMLHttpRequest的更多用法請參照:https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest#open()

如果用了fetch之後,發送一個get請求是這樣的:

//請求的網址
var url = "http://127.0.0.1:7777/list";
//發起get請求
var promise = fetch(url).then(function(response) {

   //response.status表示響應的http狀态碼
   if(response.status === 200){
     //json是傳回的response提供的一個方法,會把傳回的json字元串反序列化成對象,也被包裝成一個Promise了
     return response.json();
   }else{
     return {}
   }

});
    
promise = promise.then(function(data){
  //響應的内容
	console.log(data);
}).catch(function(err){
	console.log(err);
})
           

接下來介紹下fetch的文法:

/**
參數:
input:定義要擷取的資源。可能的值是:一個URL或者一個Request對象。
init:可選,是一個對象,參數有:
	method: 請求使用的方法,如 GET、POST。
	headers: 請求的頭資訊,形式為 Headers 對象或 ByteString。
	body: 請求的 body 資訊:可能是一個 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 對象。注意 GET 或 HEAD 方法的請求不能包含 body 資訊。
	mode: 請求的模式,如 cors、 no-cors 或者 same-origin,預設為no-cors,該模式允許來自 CDN 的腳本、其他域的圖檔和其他一些跨域資源,但是首先有個前提條件,就是請求的 method 隻能是HEAD、GET 或 POST。此外,如果 ServiceWorkers 攔截了這些請求,它不能随意添加或者修改除這些之外 Header 屬性。第三,JS 不能通路 Response 對象中的任何屬性,這確定了跨域時 ServiceWorkers 的安全和隐私資訊洩漏問題。cors模式允許跨域請求,same-origin模式對于跨域的請求,将傳回一個 error,這樣確定所有的請求遵守同源政策。
	credentials: 請求的 credentials,如 omit、same-origin 或者 include。
	cache:  請求的 cache 模式: default, no-store, reload, no-cache, force-cache, or only-if-cached.
傳回值:一個 Promise,resolve 時回傳 Response 對象。
*/
fetch(input, init).then(function(response) {  });
           

一個發送post請求的示例:

fetch("http://127.0.0.1:7777/postContent", {
  method: "POST",
  headers: {
      "Content-Type": "application/json",
  },
  mode: "cors",
  body: JSON.stringify({
      content: "留言内容"
  })
}).then(function(res) {
  if (res.status === 200) {
      return res.json()
  } else {
      return Promise.reject(res.json())
  }
}).then(function(data) {
  console.log(data);
}).catch(function(err) {
  console.log(err);
});
           

如果考慮低版本浏覽器的問題的話,引入https://github.com/github/fetch/blob/master/fetch.js 即可相容。