Fetch使用方法

前言:

  fetch是用來取代傳統的XMLHttpRequest的。 它的優勢不少,包括鏈式調用的語法、返回promise等。前端

 

什麼是fetch?

  fetch api是基於promise的設計,它是爲了取代傳統xhr的不合理的寫法而生的。node

 

WHY fetch?

  xhr請求寫起來很是的混亂,以下所示:git

var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';

xhr.onload = function() {
  console.log(xhr.response);
};

xhr.onerror = function() {
  console.log("Oops, error");
};

xhr.send();

  

  可是使用fetch以後,以下所示:github

fetch(url).then(function(response) {
  return response.json();
}).then(function(data) {
  console.log(data);
}).catch(function(e) {
  console.log("Oops, error");
});

  這種鏈式調用的風格看上去會很是舒服。ajax

 

  若是咱們再使用了箭頭函數就會更加簡潔了。 數據庫

fetch(url).then(response => response.json())
  .then(data => console.log(data))
  .catch(e => console.log("Oops, error", e))

  

  經過使用fetch api,能夠將傳統的xhr的粗糙的使用方法轉化的如此精簡,實在是好! json

 

  可是呢? 使用Promise,仍是能夠很明顯看到callback的使用,不急,咱們還能夠使用 async、await :api

// Async/Await requirements: Latest Chrome/FF browser or Babel: https://babeljs.io/docs/plugins/transform-async-to-generator/
// Fetch requirements: Latest Chrome/FF browser or Github fetch polyfill: https://github.com/github/fetch

// async function
async function fetchAsync () {
  // await response of fetch call
  let response = await fetch('https://api.github.com');
  // only proceed once promise is resolved
  let data = await response.json();
  // only proceed once second promise is resolved
  return data;
}

// trigger async function
// log response or catch error of fetch promise
fetchAsync()
    .then(data => console.log(data))
    .catch(reason => console.log(reason.message))

  這樣看上去是否是就好多了呢?跨域

注意: 對於async和await的使用仍是很明確的,就是通常咱們在一個異步函數以前添加 await 關鍵詞,而後在這個 await 的相關代碼外面使用的時 async 函數,這樣的結合纔是合適的。promise

利用 async 和 await,咱們就能夠像寫同步代碼同樣來寫異步代碼啦! 

可是呢,目前async 和 await 的支持性還不是很好,目前還沒法在通常的瀏覽器中使用!

   

 

 

 

 

 

 

 

 

 

  

基本使用方法:

fetch必須接受一個資源路徑做爲參數,而且返回了一個promise,因此咱們能夠直接使用鏈式調用的方式。 

 fetch("/getAllProduct").then(function(res) {
            return res.json();
        }).then(function (data) {
            if (data.code == 200) {
              console.log('獲取到全部產品' ,data.data);
              that.props.addAllProduct(data.data);
            } else {
              console.log(data.message);
            }
        })

這樣,咱們就能夠發送一個ajax請求。

/* 對客戶端的返回數據封裝
 * @param [code] (number) code爲返回的狀態碼
 * @param [message] (string) message爲返回的信息
 * @param [data] (any) data是可選的,爲返回給前端的數據
 */
// 注意: retrunJson中的res爲node處理接口的回調函數中的res,這個是必須的。
function returnJson(res, code, message, data) {
    var response = {
        code: code,
        message: message
    };
    if (typeof data !== 'undefined') {
        response.data = data;
    }
    res.json(response);
   // 返回這個請求以後,必需要 res.end()表示請求的結束,不然後臺可能會崩潰。 res.end(); } router.post(
'/register', function (req, res) { let userName = req.body.username, password = req.body.password, passwordAgain = req.body.passwordAgain, type = req.body.type; console.log(userName, password, type); if (type == 1) { if (password == passwordAgain) { let managerId = uuidv1(); console.log(userName, password, passwordAgain); var newUser = new Manager({ name: userName, password: password, type: req.body.type, managerId: managerId }); Manager.find(userName, function (err, user) { if (err) { returnJson(res, 5001, '服務器錯誤,註冊失敗'); } else { if (user !== null) { returnJson(res, 4003, "此用戶已經註冊!"); } else { // 若是符合條件,就註冊該用戶,將數據保存在數據庫。 newUser.save(function (err, user) { if (err) { // 服務器端錯誤,失敗返回狀態碼500 returnJson(res, 500, "用戶註冊失敗!"); } else { // user數據較簡單,直接傳遞user便可,若是複雜,咱們能夠考慮使用對象形式傳遞更多數據。 returnJson(res, 200, "用戶註冊成功!", user); } }); } } }); } else { returnJson(res, 4001, "用戶兩次輸入密碼不一致!"); } } else if( type == 2) { if (password == passwordAgain) { let userId = uuidv1(); console.log(userName, password, passwordAgain); var newUser = new User({ name: userName, password: password, type: req.body.type, userId: userId }); User.find(userName, function (err, user) { if (err) { returnJson(res, 5001, '服務器錯誤,註冊失敗'); } else { if (user !== null) { returnJson(res, 4003, "此用戶已經註冊!"); } else { // 若是符合條件,就註冊該用戶,將數據保存在數據庫。 newUser.save(function (err, user) { if (err) { // 服務器端錯誤,失敗返回狀態碼500 returnJson(res, 500, "用戶註冊失敗!"); } else { // user數據較簡單,直接傳遞user便可,若是複雜,咱們能夠考慮使用對象形式傳遞更多數據。 returnJson(res, 200, "用戶註冊成功!", user); } }); } } }); } else { returnJson(res, 4001, "用戶兩次輸入密碼不一致!"); } } });

這樣,咱們就能夠處理一個ajax請求。

 

 

 

 

注意點:

一、fetch() 返回的是一個Promise對象。

  fetch使用的promise對象能夠使得咱們使用同步的方式寫異步函數。

 

二、 fetch api是能夠結合 async 和 await 來使用的。 

  fetch是基於promise實現的,可是使用promise的寫法,咱們仍是能夠看到callback的影子,若是結合 async和await來使用,仍是很是不錯的。

 

三、 Fetch api 提供的spi囊括可是不限於xhr的全部功能。

 

四、 fetch api 能夠跨域。 

  參考: https://fetch.spec.whatwg.org/#http-cors-protocol

  跨域請求必須包括  Origin 做爲header. 

     以上。

    咱們在發送fetch請求的時候就會使用到CORS協議,儘管這些對於開發者來講是透明的,可是瀏覽器仍是會發送 origin 字段。 

 

五、fetch提供了對request和response對象的通用定義。

  Fetch 提供了對 Request 和 Response (以及其餘與網絡請求有關的)對象的通用定義。所以在一個Fetch請求中,徹底能夠只使用Request 和 Response兩個對象,經過Request 設置參數,經過Response 對返回值進行處理。 

 因此,咱們能夠將一個fetch定義以下:

var myHeaders = new Headers();
myHeaders.append('Content-Type', 'image/jpeg');
var option = { method: 'GET',
    headers: myHeaders,
    mode: 'cors',
    cache: 'default' };
var myRequest = new Request('https://api.github.com/users/mzabriskie',option);
fetch(myRequest).then(function(response) {
    ... 
});

  

 

   

參考文章: https://github.com/camsong/blog/issues/2

相關文章
相關標籤/搜索