Fetch:下一代 Ajax 技術

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

 

簡單回顧下歷史html

  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月


使用步驟大概以下java

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 處理,典型的 "事件模式"。git


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

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 都已支持,詳見web

 

以上是一個最簡單的請求,只要傳一個參數 url 過去,默認爲 get 請求,獲取純文本,fetch 第二個參數能夠進行不少配置,好比 POST 請求ajax

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, 以下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 對象,它有以下方法api

  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

相關文章
相關標籤/搜索