我正在构建Google Chrome扩展程序。基本设置是我有一个浏览器操作按钮,当点击它来执行它时,它会将jQuery和另一部分JavaScript注入活动选项卡。
这是我的第一个Chrome扩展程序,但似乎用户点击该按钮以便第二次重新注入脚本时执行操作。这是一个问题,因为它将使用的主要页面都是AJAX,因此页面内容会发生显着变化,但实际页面URL永远不会更改。
这是一个合理的问题,还是我在想它,是否有一种简单的方法可以阻止脚本多次注入同一页面?我应该将这些指定为内容脚本吗?
答案 0 :(得分:3)
这绝对是一个合理的问题。
简单的方法是使用类似于#ifndef
的机制,包括C中的警卫。
定义一个内容脚本执行后设置的标志,并在执行任何操作之前检查它是否已定义。从同一扩展注入的所有脚本共享JS执行上下文,因此共享全局范围。
您的内容脚本可能如下所示:
if(!window.contentScriptInjected){
contentScriptInjected = true; // global scope
/* Do your initialization and work */
}
/* global function definitions */
答案 1 :(得分:0)
我相信更好的方法可能是在扩展级别上进行。如果包含第三方库,那么您也将重新包含它们,并且永远不知道会发生什么。
contentScript.js
(function () {
var Sz = Sizzle;
//listen for events from the extension
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (!request._extension || request._extension !== 'my-extension-name') {
console.log('Non extension request');
return;
}
var channel = (request._channel) ? request._channel : false;
if (channel === 'is-loaded') {
sendResponse({isLoaded: true});
return true;
} else if (channel === 'example') {
//do stuff
}
return true;
});
//other code goes here
});
Background.js
var util = {};
util.sendMessage = function (data, cb) {
chrome.tabs.query({active: true, currentWindow: true}, tabsQuery_cb);
data['_extension'] = 'my-extension-name';
function tabsQuery_cb(tabs) {
var tab = tabs[0];
console.log('sending message to ' + tab.id);
console.log(data);
//let the content script know to open the ad page
chrome.tabs.sendMessage(tabs[0].id, data, cb);
}
}
util.loadContentScript = function(cb) {
var attempts = 0;
checkIfLoaded();
//checks if ContentScript is loaded by sending a message to the current
function checkIfLoaded() {
util.sendMessage({ _channel: 'is-loaded'}, sendMessage_cb);
}
function sendMessage_cb(response) {
console.log('isLoadedCheck')
console.log(response);
if (response && response.isLoaded === true) {
console.log('Script already loaded!');
cb(true);
} else {
console.log('loading scripts');
loadScripts();
}
}
function loadScripts() {
attempts++;
console.log('loadScripts, attempt no. ' + attempts);
if (attempts > 1) {
console.log('Script couldnt be loaded');
return cb(false);
}
var scripts = [
"assets/sizzle-2.3.4.min.js",
"app/contentScript.js"
];
var i = -1;
scriptLoaded();
function scriptLoaded() {
i++;
if (i > scripts.length) {
//all scripts have loaded at this point, check if replies with message
checkIfLoaded();
} else {
console.log('Loading script ' + scripts[i]);
chrome.tabs.executeScript(null, { file: scripts[i] }, scriptLoaded);
}
}
}
}
当然,包括第三方库似乎仍然是一种不好的做法,因为它可能会与网站的脚本产生偏差。但是还有其他方法。也许您可以走极端,创建一个引导内容脚本,该脚本将检查库的存在并告诉扩展脚本确切地需要包含哪些内容。这就是我要考虑的更严肃的项目。