前言

很多情况下咱们在做浏览器插件的时候需要拿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;
            });
        };

标签: none

添加新评论