Fetch:下一代 Ajax 技術


Ajax,2005年誕生的技術,至今已持續了 10 年。它是一種在客戶端創建一個異步請求的技術,本質上它不算創新,是一組技術的組合。它的核心對象是 XMLHttpRequest。

 

簡單回顧下歷史

  1. 1996年,IE 中首先添加了 iframe 用來實現異步請求獲取服務器內容
  2. 1998年,微軟 Outlook 在客戶端 script 中實現了 XMLHttp 對象
  3. 1999年,微軟在 IE5 中添加了 XMLHTTP ActiveX 對象用來異步獲取服務器內容,該對象直到 Edge 瀏覽器才廢棄。其它瀏覽器陸續實現了類似的對象稱為 XMLHttpRequest
  4. 2004年,Google Gmail 中大量使用 XMLHttpRequest
  5. 2005年,Google Map 中大量使用 XMLHttpRequest
  6. 2005年,Jesse James Garrett 發表了文章 "Ajax: A New Approach to Web Applications",Ajax 誕生
  7. 2006年,XMLHttpRequest 被 W3C 采納,最后更新時間是 2014年1月


使用步驟大概如下

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

xhr.onload = function() {
	// To do with xhr.response
};

xhr.onerror = function() {
	// Handling errors
};

xhr.send();

 

以上可以看出,XHR 使用 onXXX 處理,典型的 "事件模式"。


Fetch 目前還不是 W3C 規范,由 whatag 負責出品。與 Ajax 不同的是,它的 API 不是事件機制,而采用了目前流行的 Promise 方式處理。我們知道 Promise 是已經正式發布的 ES6 的內容之一。

fetch('doAct.action').then(function(res) {
    if (res.ok) {
        res.text().then(function(obj) {
            // Get the plain text
        })
    }
}, function(ex) {
    console.log(ex)
})

以上 fetch 函數是全局的,目前最新的Firefox,Chrome,Opera 都已支持,詳見

 

以上是一個最簡單的請求,只要傳一個參數 url 過去,默認為 get 請求,獲取純文本,fetch 第二個參數可以進行很多配置,比如 POST 請求

fetch("doAct.action", {
	method: "POST",
	headers: {
		"Content-Type": "application/x-www-form-urlencoded"
	},
	body: "keyword=榮耀7i&enc=utf-8&pvid=0v3w1kii.bf1ela"
}).then(function(res) {
	if (res.ok) {
		// To do with res
	} else if (res.status == 401) {
		// To do with res
	}
}, function(e) {
	// Handling errors
});

 

如果返回的是 JSON, 如下

fetch('doAct.action').then(function(res) {
    if (res.ok) {
        res.json().then(function(obj) {
            // Get the JSON
        })
    }
}, function(ex) {
    console.log(ex)
})

res 實際上該規范定義的 Response 對象,它有如下方法

  1. arrayBuffer()
  2. blob()
  3. json()
  4. text()
  5. formData()

 

此外,Fetch 跨域請求時默認不會帶 cookie,需要時得手動指定 credentials: 'include'

fetch('doAct.action', {credentials: 'include'}).then(function(res) {
	// ...
})

這和 XHR 的 withCredentials 一樣,只是 withCredentials 只要設為 true。

 

Fecth 獲取 HTTP 頭信息非常容易

// 取HTTP頭信息
fetch('doAct.action').then(function(response) {  
    console.log(response.headers.get('Content-Type'));  
    console.log(response.headers.get('Date'));
});

 

Fetch 也可以鏈式使用

// 示例4:鏈式調用
function status(response) {  
  if (response.status >= 200 && response.status < 300) {  
    return Promise.resolve(response)  
  } else {  
    return Promise.reject(new Error(response.statusText))  
  }  
}

function json(response) {  
  return response.json()  
}

fetch('doAct.action')  
  .then(status)  
  .then(json)  
  .then(function(data) {  
    console.log('Request succeeded with JSON response', data);  
  }).catch(function(error) {  
    console.log('Request failed', error);  
  });

 

Fetch 模擬表單提交

fetch('doAct.action', {  
    method: 'post',  
    headers: {  
      "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"  
    },  
    body: 'foo=bar&lorem=ipsum'  
  })
  .then(json)  
  .then(function (data) {  
    console.log('Request succeeded with JSON response', data);  
  })  
  .catch(function (error) {  
    console.log('Request failed', error);  
  });

  

相關:

https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalFetch/fetch
https://fetch.spec.whatwg.org
https://hacks.mozilla.org/2015/03/this-api-is-so-fetching

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM