javascript - chrome 扩展在任何其他 js 之前在头顶注入(inject) javascript

标签 javascript google-chrome google-chrome-extension

我想做什么。

使用 Chrome 扩展程序,我需要将脚本注入(inject)页面上下文,注入(inject)的脚本在页面上任何其他 javascript 之前运行。

我为什么需要这个?

我需要劫持特定页面的所有 console 命令,以便我的扩展程序可以收听消息。

我当前的问题

目前我正在捕获页面记录的一些消息,但不是全部,特别是来自 web-directory-132a3f16cf1ea31e167fdf5294387073.js 的所有消息都没有被捕获。经过一些挖掘后,我发现 web-directory-132a3f16cf1ea31e167fdf5294387073.js 也是劫持 console之前我的脚本有机会。

作为视觉效果,如果我在加载页面后查看网络选项卡,我会看到:

enter image description here

我注入(inject)的脚本是consoleInterceptor.js。它正确捕获此处加载的 js 文件的输出 accept web-directory-132a3f16cf1ea31e167fdf5294387073.js

web-directory-132a3f16cf1ea31e167fdf5294387073.js 的内部是一些类似这样的代码:

   ....
    _originalLogger: t.default.Logger,
   ...
    // do stuff with logging ....
    this._originalLogger[e].apply(this._originalLogger, s),

我认为问题是什么

在我看来,web-directory-132a3f16cf1ea31e167fdf5294387073.js 正在获取标准的console 函数并在我的脚本之前将它们存储在内部有机会用我自己的版本替换它们。因此,即使我的脚本有效,web-directory-132a3f16cf1ea31e167fdf5294387073.js 仍然使用它保存的原始标准控制台功能。

请注意,web-directory-132a3f16cf1ea31e167fdf5294387073.js 是一个 ember 应用程序,我没有看到任何简单的方法来连接到该代码以覆盖这些函数,但我愿意将其作为解决方案。

我当前的代码:

list .js

  ...
  "web_accessible_resources": [
    "js/ajaxInterceptor.js",
    "js/consoleInterceptor.js"
  ],
  "version" : "5.2",
  "manifest_version": 2,
  "permissions": [
    "<all_urls>",
    "tabs",
    "activeTab",
    "storage",
    "webNavigation",
    "unlimitedStorage",
    "notifications",
    "clipboardWrite",
    "downloads",
    "tabCapture",
    "cookies",
    "browsingData",
    "webRequest",
    "*://*/*",
    "gcm",
    "contextMenus",
    "management"
  ],
  "externally_connectable": {
    "matches": ["*://apps.mypurecloud.com/*","*://*.cloudfront.net/*"]
  },
  ...

background.js

var options = {url: [{hostContains: 'apps.mypurecloud.com'}]};
chrome.webNavigation.onCommitted.addListener(function(details) {
        // first inject the chrome extension's id
        chrome.tabs.executeScript(details.tabId, {
            code: "var chromeExtensionId = " + JSON.stringify(chrome.runtime.id)
        });
        // then inject the script which will use the dynamically added extension id
        // to talk to the extension
        chrome.tabs.executeScript(details.tabId, {
            file: 'js/injectConsoleInterceptor.js'
        });
    },
    options
);
chrome.runtime.onMessageExternal.addListener(
    function(msg, sender, sendResponse) {
        if(msg.action === 'console_intercepted'){
            _this.processConsoleMessage(sender, msg.details.method, msg.details.arguments);

        }
    });

injectConsoleInterceptor.js

var interceptorScript = document.createElement('script');
interceptorScript.src = chrome.extension.getURL('js/consoleInterceptor.js');
interceptorScript.onload = function(){this.remove();};
(document.head || document.documentElement).prepend(interceptorScript);

consoleInterceptor.js

if(!window.hasConsoleInterceptor){
    window.hasConsoleInterceptor = true;
    console.log('overriding console functions');
    var originals ={};
    var console = window.console;
    if (console){
        function interceptConsoleMethod(method){
            originals[method] = console[method];
            console[method] = function(){
                // send the data to the extension
                // chromeExtensionId should be injected into the page separately and before this script
                var data = {
                    action: 'console_intercepted',
                    details: {
                        method: method,
                        arguments: arguments
                    }
                };
                chrome.runtime.sendMessage(chromeExtensionId, data);
                originals[method].apply(console, arguments)
            }
        }
        // an array of the methods we want to observe 
        var methods = ['assert', 'count', 'debug', 'dir', 'dirxml', 'error', 'group','groupCollapsed','groupEnd','info','log', 'profile', 'profileEnd','time','timeEnd','timeStamp','trace','warn','table'];
        for (var i = 0; i < methods.length; i++){
            interceptConsoleMethod(methods[i])
        }
        console.log('Successfully overridden console functions: '+methods.join(','));
    }
}

我的问题

我该怎么做才能使 consoleInterceptor.jsweb-directory-132a3f16cf1ea31e167fdf5294387073.js 加载之前运行,以便 web-directory-132a3f16cf1ea31e167fdf5294387073.js 使用我修改过的控制台函数而不是默认的浏览器控制台函数?

最佳答案

你可以试试这个。

在 manifest.json 文件中:


    "content_scripts": [
            {
              "matches": ["http://*/*", "https://*/*"],
              "js": ["script/inject.js"],
              "run_at":"document_start"
            }
        ]

In inject.js:

var ss = document.createElement("script");
ss.innerHTML= "xxx";
document.documentElement.appendChild(ss);

关于javascript - chrome 扩展在任何其他 js 之前在头顶注入(inject) javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45247355/

相关文章:

javascript - Angular javascript 缩小导致错误 : $injector:modulerr Module Error

javascript - 在 Vanilla javascript中向ajax帖子添加变量

javascript - 访问 Chrome unsafeWindow

html - CSS 过滤器 : Wikipedia: Inline math's background is not transparent

javascript - 如何使用 PhoneGap 保存网页供离线使用?

javascript - 堆栈跟踪中的 node.js 文件位于何处?

html - 在 Mac/safari 或 chrome 上选择框 `appearance`

javascript - 是否可以在没有 onPaste 处理程序的情况下读取 Chrome 中的剪贴板内容?

javascript - 如何在 Chrome 上以编程方式禁用向右滑动手势?

rest - 如何使用 Chrome 扩展程序 "Advanced Rest Client"测试 REST API