摘要:首先聲明一下,本文不是要講解的具體用法,不清楚的可以參考教程。該模式用于跨域請求但是服務器不帶響應頭,也就是服務端不支持這也是的特殊跨域請求方式其對應的為。
首先聲明一下,本文不是要講解fetch的具體用法,不清楚的可以參考 MDN fetch教程。
fetch默認不攜帶cookie配置其 credentials 項,其有3個值:
omit: 默認值,忽略cookie的發送
same-origin: 表示cookie只能同域發送,不能跨域發送
include: cookie既可以同域發送,也可以跨域發送
credentials所表達的含義,其實與XHR2中的withCredentials屬性類似,表示請求是否攜帶cookie
這樣,若要fetch請求攜帶cookie信息,只需設置一下credentials選項即可,例如fetch(url, {credentials: "include"});
fetch請求對某些錯誤http狀態不會reject這主要是由fetch返回promise導致的,因為fetch返回的promise在某些錯誤的http狀態下如400、500等不會reject,相反它會被resolve;只有網絡錯誤會導致請求不能完成時,fetch 才會被 reject;所以一般會對fetch請求做一層封裝,例如下面代碼所示:
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 )); }fetch不支持超時timeout處理
方法一:單純setTimeout方式
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功能:
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]) }fetch不支持JSONP
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) })fetch不支持progress事件
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跨域問題
fetch的mode配置項有3個值,如下:
same-origin:該模式是不允許跨域的,它需要遵守同源策略,否則瀏覽器會返回一個error告知不能跨域;其對應的response type為basic。
cors: 該模式支持跨域請求,顧名思義它是以CORS的形式跨域;當然該模式也可以同域請求不需要后端額外的CORS支持;其對應的response type為cors。
no-cors: 該模式用于跨域請求但是服務器不帶CORS響應頭,也就是服務端不支持CORS;這也是fetch的特殊跨域請求方式;其對應的response type為opaque。
參考MDN-ReadableStream
MDN fetch
https://segmentfault.com/a/1190000008484070#articleHeader3
友情鏈接前端知識體系
react服務端渲染博客
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104284.html
首先聲明一下,本文不是要講解fetch的具體用法,不清楚的可以參考MDN fetch教程。 引言 說道fetch就不得不提XMLHttpRequest了,XHR在發送web請求時需要開發者配置相關請求信息和成功后的回調,盡管開發者只關心請求成功后的業務處理,但是也要配置其他繁瑣內容,導致配置和調用比較混亂,也不符合關注分離的原則;fetch的出現正是為了解決XHR存在的這些問題。例如下面代碼: f...
摘要:基于全家桶寫作新聞一體綜合應用的實踐總結在線地址大家伙兒們,又見面了。參照但不可否認非常符合的思想,都在處理大規模數據時彰顯優勢。最好的辦法是使用部署環境。細致的拆分,解耦性更好,以為單位進行修改時,大大降低誤傷率的同時,隔離無關的信息。 ?CoderPad-基于React全家桶寫作/新聞一體綜合應用的實踐總結 showImg(https://segmentfault.com/img/...
摘要:關聯關系的關聯關系定義上,感覺并不是很靈活,姿勢也比較難找。如,定義在關聯關系上的參數可以設置級聯的相關東西。因為序列化會涉及到實體類關聯對象的獲取,會觸發所有的關聯關系。 接(4) - Database 系列. Java Persistence API,可以理解就是 Java 一個持久化標準或規范,Spring Data JPA 是對它的實現。并且提供多個 JPA 廠商適配,如 Hi...
摘要:原文今天折騰了一天終于把版本安裝完成了,問題最多的就是安裝區塊問題,官方文檔可以在項目跟目錄中執行來下載所有的區塊。得到的界面將與中相同。此時,打開下面發現一個區塊都沒安裝上。 原文:https://www.dayuzy.com/?p=481 今天折騰了一天終于把ant Design Pro v4.0版本安裝完成了,問題最多的就是安裝區塊問題,官方文檔: 可以在 pro 項目跟目錄中...
摘要:明天就是中秋節了現在的實驗室空空蕩蕩的只剩下我們幾個了提前祝大家中秋快樂 最近, 耗子我在做關于互聯網新聞分類的項目, 需要用到sklearn.datasets里新聞數據抓取器fetch_20newsgroups, 而當將參數subset設置為all時, fetch_20newsgroups需要即時從互聯網下載數據, So: showImg(https://segmentfault.c...
閱讀 1756·2021-11-24 09:39
閱讀 1686·2021-11-22 15:22
閱讀 1002·2021-09-27 13:36
閱讀 3229·2021-09-24 10:34
閱讀 3328·2021-07-26 23:38
閱讀 2632·2019-08-29 16:44
閱讀 973·2019-08-29 16:39
閱讀 1103·2019-08-29 16:20