javascript 浏览器扩展:猴子补丁从实际网页获取响应

0yycz8jy  于 9个月前  发布在  Java
关注(0)|答案(1)|浏览(82)

我正在开发一个浏览器扩展,目前在content_scripts下运行脚本。
我正试图从我的扩展运行到的网站上截取获取请求的响应。
我找到了很多关于如何猴子补丁获取请求来拦截响应的答案。但我的问题是,虽然我可以很好地拦截我自己的请求(在Chrome中),但I can't access the ones from the website itself
显然是there is a way to inject code in a tab,但是,再一次,我运行的问题是I can't run browser.tabs from content_script

在JavaScript中,有什么方法可以让我获得一个扩展来拦截来自网页的获取请求(特别是响应)?

可能不是很相关,但我现在的代码是对a stackoverflow answer的轻微修改,如下所示:

const isFirefox = navigator.userAgent.toLowerCase().includes('firefox');

if(!isFirefox){
    const {fetch: origFetch} = window;
    let responseData = null;
    window.fetch = async (...args) => {
      console.log("fetch called with args:", args);
      let response = await origFetch(...args);
      console.log("test2"); //Firefox will never get here
      // work with the cloned response in a separate promise
      // chain -- could use the same chain with `await`. 
      await response
        .clone()
        .json()
        .then(function(data){
            console.log("intercepted response data:", data);
            responseData = data;
            })
        .catch(err => console.error(err));

      // the original response can be resolved unmodified:
      console.log(responseData);
      //return response;

      // or mock the response: 
      return new Response(JSON.stringify(responseData));
    };
}

字符串

shyt4zoc

shyt4zoc1#

以下是我实现目标的一个方法:
在content_scripts中,我添加了以下代码来在主世界中注入一个JavaScript文件:

//Inject the script into the main environment.
var s = document.createElement('script');
s.src = chrome.runtime.getURL('scripts/attach.js');
s.onload = function() { this.remove(); };
// see also "Dynamic values in the injected code" section in this answer
(document.head || document.documentElement).appendChild(s);

字符串
然后我的 scripts/attach.js 将在主世界/环境中执行,并对fetch方法进行猴子补丁以拦截响应并允许修改它:

const origFetch = window.fetch;

let responseData = {};

window.fetch = async (...args) => {
  
  let response = await origFetch(...args);

  //Will only work for content which can be encoded to JSON. This code should not be used for images or other binary content. For those content, just return response.
      await response
        .clone()
        .json()
        .then(function(data){
            responseData = data;
            })
        .catch(err => console.error(err));
        
    //Modify responseData
      
    //Return mocked response
    return new Response(JSON.stringify(responseData));
  
    //Return unaltered response
    //return response;
  }
};

相关问题