我希望我的Chrome扩展程序仅适用于新闻网站,因此我列出了许多我想限制的网址。
是否有一种更简单的方法来限制我的扩展程序,而不是在"matches"
的{{1}}字段中手动添加长列表?谢谢!
manifest.json
答案 0 :(得分:2)
我首先要说的是,在列表的所有网站中注入内容脚本的“最简单”方法实际上是将它们添加到扩展程序清单中"matches"
的数组中。
如果您担心必须手动在阵列中插入每个站点,那么这没什么大不了的,您可以轻松地将其粘贴到文本编辑器中并使用查找和替换来执行您想要的操作,例如替换{{1} }使用\n
,然后手动编辑第一个和最后一个:
/*",\n"*://
完成后,您只需将其复制并粘贴到site1.com -> site1.com/*", -> "*://site1.com/*",
site2.net -> "*://site2.net/*", -> "*://site2.net/*",
site3.org -> "*://site3.org/*", -> "*://site3.org/*"
"*//
数组
"matches": [ ...
API 如果您真的不想在清单中添加它们,可以将它们放在扩展程序目录中的文本文件中,然后将其加载到后台页面并添加一个监听器tabs
以检查何时如果新URL与其中一个站点匹配,则URL会更改并注入脚本。这个恕我直言比简单地在你的清单中添加它们更复杂。
工作示例
您的chrome.tabs.onUpdated
:
list.txt
您的site1.com
site2.net
site3.org
脚本:
background.js
不要忘记同时添加// Function to extract the hostname from an URL.
function getHostname(url) {
return url.match(/^(.*:)\/\/([A-Za-z0-9\-\.]+)/)[2];
}
// XHR to get the list.txt
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// Parse the list and create a set from it:
var list = new Set(xhr.responseText.split('\n'));
// Listen for tabs.onUpdated:
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
// If the tab changed URL:
if (changeInfo.url)
// If the new URL is one of the sites in the list:
if (list.has(getHostname(changeInfo.url)))
// Inject the script:
chrome.tabs.executeScript(tabId, {file: 'yourScript.js'});
});
}
});
xhr.open('GET', 'list.txt', true);
xhr.send();
的权限(因为您要在未直接列出的网站中注入脚本),以及清单中的<all_urls>
API:
chrome.tabs
...
"permissions": ["<all_urls>", "tabs"],
...
API 与前一个类似,但更简单:解析declarativeContent
并创建一个由list.txt
API处理的新规则。您无需担心手动匹配网址,Chrome会运行匹配并为您优化规则。
chrome.declarativeContent
注意以上代码全部包含在chrome.runtime.onInstalled.addListener(function() {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var list = xhr.responseText.split('\n');
// Create a new rule with an array of conditions to match all the sites:
var rule = {
conditions: list.map(site => new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostEquals: site, schemes: ['http', 'https'] }
})),
// To inject the script when the conditions are met:
actions: [new chrome.declarativeContent.RequestContentScript({js: ['yourScript.js']})]
}
// And register it:
chrome.declarativeContent.onPageChanged.addRules([rule]);
}
});
});
xhr.open('GET', 'list.txt', true);
xhr.send();
});
侦听器中,因为chrome.runtime.onInstalled
规则是持久的,并且您不需要每次添加它们扩展开始。
在这种情况下,您的清单中的declarativeContent
和"<all_urls>"
都需要获得许可:
"declarativeContent"
现在,有了这个说法,我实际上认为最简单的方式来做你想要的只是简单地在扩展名清单的...
"permissions": ["<all_urls>", "declarativeContent"],
...
字段中添加网站,但是你你可以自由地做你认为最好的事情。我实际上经常使用第二种方法,但总体而言如果您不想在"matches"
中手动添加匹配规则,则第三种方法效率最高。
如果您想了解更多信息,请查看我在示例中使用的方法和类型的文档:
答案 1 :(得分:0)
我一直在寻找适用于该框架的答案,但后来在Javascript
内并为活动标签创建了直接Listener
。我还想使用定义的函数,而不是加载单独的Javascript
文件。
我的最终目标是让扩展程序响应热键,但仅适用于特定主机。这是我的方法:
在manifest.json
中:
...
"commands": {
"some-command": {
"suggested_key": {
"default": "Ctrl+Shift+L"
},
"description": "Tell me something special."
}
},
...
在background.js
中:
chrome.commands.onCommand.addListener(function(command) {
chrome.tabs.getSelected(null, function(tab) {
var url = new URL(tab.url);
if (url.hostname != 'somedomain.com') return;
if (command == 'some-command') {
custom_function();
}
});
});
function custom_function {}
最终结果是,无论触发热键命令还是通过地址栏弹出窗口,该扩展名仅适用于具有特定域名的选项卡。我没有包括地址栏弹出代码,因为它就在“构建Chrome扩展程序”指南中-我希望这一切已经完成。