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

问题描述 投票:0回答:1

我正在开发一个浏览器扩展,当前正在 content_scripts 下运行脚本。

我正在尝试拦截来自我的扩展程序运行的网站的获取请求的响应。

我找到了很多关于如何猴子修补获取请求以拦截响应的答案。但我的问题是,虽然我可以很好地拦截自己的请求(在 Chrome 中),但我无法从网站本身访问这些请求

显然有一种方法可以在选项卡中注入代码,但是,我再次遇到问题我无法从content_script运行browser.tabs

在 javascript 中,我可以通过哪些方式获得扩展来拦截来自网页的获取请求(特别是响应)?

可能不是很相关,但我当前的代码是对stackoverflow答案的轻微改编,如下:

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));
    };
}
javascript google-chrome-extension code-injection monkeypatching browser-extension
1个回答
0
投票

这是我实现目标的方法:

在 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;
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.