简体   繁体   English

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

[英]chrome extension inject javascript at top of head before any other js

What I want to do. 我想做的事。

Using a Chrome extension I need to inject a script into the page context in such a way that the injected script runs before any other javascript on the page. 使用Chrome扩展程序我需要将一个脚本注入页面上下文,使注入的脚本在页面上的任何其他javascript之前运行。

Why do I need this? 我为什么需要这个?

I need to hijack all console commands for a specific page so my extension can listen to the messages. 我需要劫持特定页面的所有console命令,以便我的扩展程序可以收听消息。

My current issue 我目前的问题

Currently I am catching some of the messages logged by the page but not all of them, specifically, all messages from web-directory-132a3f16cf1ea31e167fdf5294387073.js are not being caught. 目前我正在捕捉页面记录的一些消息,但不是所有消息,特别是来自web-directory-132a3f16cf1ea31e167fdf5294387073.js所有消息都没有被捕获。 After some digging I discovered that the web-directory-132a3f16cf1ea31e167fdf5294387073.js is also hijacking console but doing so before my script has a chance to. 经过一番挖掘后,我发现web-directory-132a3f16cf1ea31e167fdf5294387073.js 也在劫持console我的脚本有机会之前这样做了。

As a visual, if I look at the network tab after loading the page, I see this: 作为一个视觉,如果我在加载页面后查看网络选项卡,我看到:

在此输入图像描述

My injected script is consoleInterceptor.js . 我注入的脚本是consoleInterceptor.js It correctly captures the output of the js files that are loaded here accept web-directory-132a3f16cf1ea31e167fdf5294387073.js 它正确捕获了这里加载的js文件的输出接受web-directory-132a3f16cf1ea31e167fdf5294387073.js

Inside of web-directory-132a3f16cf1ea31e167fdf5294387073.js is some code something like this: web-directory-132a3f16cf1ea31e167fdf5294387073.js是一些像这样的代码:

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

What I think the problem is 我认为问题是什么

It seems to me that, web-directory-132a3f16cf1ea31e167fdf5294387073.js is grabbing the standard console functions and storing them internally before my script has had a chance to replace them with my own versions. 在我看来, web-directory-132a3f16cf1ea31e167fdf5294387073.js正在抓取标准console功能并我的脚本有机会用我自己的版本替换之前将它们存储在内部。 So even though my script works, the web-directory-132a3f16cf1ea31e167fdf5294387073.js still uses the original standard console functions it saved. 因此,即使我的脚本有效, web-directory-132a3f16cf1ea31e167fdf5294387073.js仍然使用它保存的原始标准控制台功能。

Note that web-directory-132a3f16cf1ea31e167fdf5294387073.js is an ember application and I dont see any simple way to hook into that code to overwrite those functions too but Im open to that as a solution. 请注意, web-directory-132a3f16cf1ea31e167fdf5294387073.js是一个ember应用程序,我没有看到任何简单的方法来挂钩代码来覆盖这些函数,但我作为一个解决方案对此开放。

My current code: 我目前的代码:

manifest.js manifest.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 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 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 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(','));
    }
}

My question 我的问题

What can I do to make consoleInterceptor.js run before web-directory-132a3f16cf1ea31e167fdf5294387073.js loads so that web-directory-132a3f16cf1ea31e167fdf5294387073.js uses my modified console functions rather than the default browser console funcitons? 我能做些什么,使consoleInterceptor.js之前运行web-directory-132a3f16cf1ea31e167fdf5294387073.js负载,使web-directory-132a3f16cf1ea31e167fdf5294387073.js使用我修改控制台的功能,而不是默认的浏览器控制台funcitons?

You can try this. 你可以试试这个。

In manifest.json file: 在manifest.json文件中:

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

In inject.js: 在inject.js中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM