我想做什么。
使用 Chrome 扩展程序,我需要将脚本注入(inject)页面上下文,注入(inject)的脚本在页面上任何其他 javascript 之前运行。
我为什么需要这个?
我需要劫持特定页面的所有 console
命令,以便我的扩展程序可以收听消息。
我当前的问题
目前我正在捕获页面记录的一些消息,但不是全部,特别是来自 web-directory-132a3f16cf1ea31e167fdf5294387073.js
的所有消息都没有被捕获。经过一些挖掘后,我发现 web-directory-132a3f16cf1ea31e167fdf5294387073.js
也是劫持 console
但之前我的脚本有机会。
作为视觉效果,如果我在加载页面后查看网络选项卡,我会看到:
我注入(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.js
在 web-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/