前言
很多情況下咱們在做瀏覽器插件的時候需要拿fetch的返回數據而不影響功能正常操作。
原理
hook原理咱就不講了,跟其他hook差不多。具體來看看如何實現返回的。
用過fetch的朋友應該都知道response.body只能讀一下,那么如何在影響功能的情況下獲取數據呢?
咱們想一下是不是可以克隆一個返回的body數據出來呢,不影響原數據的情況下。
通過博主的實現發現使用Object.assign是無法克隆的。
細心的小伙伴應該發現了body數據返回的類型是ReadableStream,只讀流。
那么我們是否可以通過new ReadableStream來實現讀取返回數據而不影響后續功能呢?
最終原理嗎,就是通過把原fetch的response數據攔截了,然后返回一個新的未更改的response對象。
最終代碼放結尾。
文檔https://developer.mozilla.org/zh-CN/docs/Web/API/ReadableStream
代碼
咱們先看一下下面這段代碼
window.au_fetch=window.fetch;
window.fetch=function(url){
return window.au_fetch.apply(window,arguments).then((response) => {
const reader = response.body.getReader();
const stream = new ReadableStream({
start(controller) {
function push() {
// "done"是一個布爾型,"value"是一個Unit8Array
reader.read().then((e) => {
let { done, value }=e;
// 判斷是否還有可讀的數據?
console.log(done,new TextDecoder("utf-8").decode(value));
if (done) {
// 告訴瀏覽器已經結束數據發送
controller.close();
return;
}
// 取得數據並將它通過controller發送給瀏覽器
controller.enqueue(value);
push();
});
}
push();
}
});
let ret=new Response(stream, { headers: { "Content-Type": "text/html" } })
console.log(stream,ret);
return ret;
});
};