首先聲明一下,本文不是要講解fetch的具體用法,不清楚的能夠參考 MDN fetch教程。前端
配置其 credentials 項,其有3個值:react
credentials所表達的含義,其實與XHR2中的withCredentials屬性相似,表示請求是否攜帶cookiegit
這樣,若要fetch請求攜帶cookie信息,只需設置一下credentials選項便可,例如fetch(url, {credentials: 'include'});github
這主要是由fetch返回promise致使的,由於fetch返回的promise在某些錯誤的http狀態下如400、500等不會reject,相反它會被resolve;只有網絡錯誤會致使請求不能完成時,fetch 纔會被 reject;因此通常會對fetch請求作一層封裝,例以下面代碼所示:npm
function checkStatus(response) { if (response.status >= 200 && response.status < 300) { return response; } const error = new Error(response.statusText); error.response = response; throw error; } function parseJSON(response) { return response.json(); } export default function request(url, options) { let opt = options||{}; return fetch(url, {credentials: 'include', ...opt}) .then(checkStatus) .then(parseJSON) .then((data) => ( data )) .catch((err) => ( err )); }
方法一:單純setTimeout方式json
var oldFetchfn = fetch; //攔截原始的fetch方法 window.fetch = function(input, opts){//定義新的fetch方法,封裝原有的fetch方法 return new Promise(function(resolve, reject){ var timeoutId = setTimeout(function(){ reject(new Error("fetch timeout")) }, opts.timeout); oldFetchfn(input, opts).then( res=>{ clearTimeout(timeoutId); resolve(res) }, err=>{ clearTimeout(timeoutId); reject(err) } ) }) }
固然在上面基礎上能夠模擬相似XHR的abort功能:segmentfault
var oldFetchfn = fetch; window.fetch = function(input, opts){ return new Promise(function(resolve, reject){ var abort_promise = function(){ reject(new Error("fetch abort")) }; var p = oldFetchfn(input, opts).then(resolve, reject); p.abort = abort_promise; return p; }) }
方法二:利用Promise.race方法
Promise.race方法接受一個promise實例數組參數,表示多個promise實例中任何一個最早改變狀態,那麼race方法返回的promise實例狀態就跟着改變,具體能夠參考這裏。後端
var oldFetchfn = fetch; //攔截原始的fetch方法 window.fetch = function(input, opts){//定義新的fetch方法,封裝原有的fetch方法 var fetchPromise = oldFetchfn(input, opts); var timeoutPromise = new Promise(function(resolve, reject){ setTimeout(()=>{ reject(new Error("fetch timeout")) }, opts.timeout) }); retrun Promise.race([fetchPromise, timeoutPromise]) }
npm install fetch-jsonp --save-dev
而後在像下面同樣使用:跨域
fetchJsonp('/users.jsonp', { timeout: 3000, jsonpCallback: 'custom_callback' }) .then(function(response) { return response.json() }).catch(function(ex) { console.log('parsing failed', ex) })
XHR是原生支持progress事件的,例以下面代碼這樣:數組
var xhr = new XMLHttpRequest() xhr.open('POST', '/uploads') xhr.onload = function() {} xhr.onerror = function() {} function updateProgress (event) { if (event.lengthComputable) { var percent = Math.round((event.loaded / event.total) * 100) console.log(percent) } xhr.upload.onprogress =updateProgress; //上傳的progress事件 xhr.onprogress = updateProgress; //下載的progress事件 } xhr.send();
可是fetch是不支持有關progress事件的;不過可喜的是,根據fetch的指導規範標準,其內部設計實現了Request和Response類;其中Response封裝一些方法和屬性,經過Response實例能夠訪問這些方法和屬性,例如response.json()、response.body等等;
值得關注的地方是,response.body是一個可讀字節流對象,其實現了一個getRender()方法,其具體做用是:
getRender()方法用於讀取響應的原始字節流,該字節流是能夠循環讀取的,直至body內容傳輸完成;
所以,利用到這點能夠模擬出fetch的progress
// fetch() returns a promise that resolves once headers have been received fetch(url).then(response => { // response.body is a readable stream. // Calling getReader() gives us exclusive access to the stream's content var reader = response.body.getReader(); var bytesReceived = 0; // read() returns a promise that resolves when a value has been received reader.read().then(function processResult(result) { // Result objects contain two properties: // done - true if the stream has already given you all its data. // value - some data. Always undefined when done is true. if (result.done) { console.log("Fetch complete"); return; } // result.value for fetch streams is a Uint8Array bytesReceived += result.value.length; console.log('Received', bytesReceived, 'bytes of data so far'); // Read some more, and call this function again return reader.read().then(processResult); }); });
fetch的mode配置項有3個值,以下: