Ste*_*ven 63 google-chrome google-chrome-extension
我正在编写Chrome扩展程序,并<div>
在popup.html文件中单击按钮后尝试覆盖当前网页.
当我document.body.insertBefore
从popup.html中访问该方法时,它会覆盖<div>
弹出窗口而不是当前网页.
我是否必须在background.html和popup.html之间使用消息传递才能访问网页的DOM?我想在popup.html中做所有事情,并且如果可能的话也使用jQuery.
Moh*_*our 105
如Chrome扩展程序概述中所述:体系结构(必读):
如果您的扩展需要与网页交互,那么它需要一个内容脚本.内容脚本是一些JavaScript,它在已加载到浏览器中的页面的上下文中执行.将内容脚本视为该加载页面的一部分,而不是作为其打包的扩展(其父扩展)的一部分.
browserAction弹出窗口是您单击浏览器工具栏中的图标时看到的页面,它是带有chrome-extension://
URL 的HTML页面,因此当您访问其DOM时,您正在影响弹出窗口.这同样适用于扩展的背景/选项页面.
要访问/操作网页DOM,您有两种方法:
chrome.tabs.sendMessage()
从你的后台/弹出页面到注入的内容脚本的chrome.runtime.onMessage
监听器,它将sendResponse
根据文档在网页上执行操作并通过回调传输结果(注意:只支持JSON可用的对象,如数字,字符串,数组,简单对象,这意味着不是DOM元素,不是类,不是函数).如果内容脚本需要启动与扩展页面的通信,它应该使用chrome.runtime.sendMessage()
.
或者使用Tabs API注入内容脚本:
chrome.tabs.executeScript(tabId, details, callback)
所需的权限:"tabs"
,"https://www.example.com/*"
(或"<all_urls>"
及其变种类似"*://*/*"
,"http://*/*"
,"https://*/*"
)
在显式用户激活的情况下,更好的选择是使用"activeTab"
权限而不是"tabs"
并且"<all_urls>"
因为它可以作为许多用途的替代"<all_urls>"
,但在安装期间不显示警告消息.
.executeScript()
可以与回调函数一起使用,该函数接收注入的内容脚本中的最后一个计算表达式的数组,每个帧中的一个元素在注册表中注入.Chrome 在内部使用JSON.parse()
和JSON.stringify()
结果,从而将支持的类型限制为普通对象和简单的可字符串值,如数字/字符串或其数组.
因此它不适用于DOM元素,函数,自定义属性,getter/setter:您需要手动映射/提取所需数据并将其传递到一个简单的数组/对象中.
内容脚本在称为孤立世界的特殊环境中执行.他们可以访问注入页面的DOM,但不能访问页面创建的任何JavaScript变量或函数.它将每个内容脚本视为在其运行的页面上没有执行其他JavaScript.反过来也是如此:页面上运行的JavaScript无法调用任何函数或访问内容脚本定义的任何变量.
仍然可以更深入地访问网页JavaScript变量/函数.
作为第二种方法的示例,让我们在单击浏览器操作时显示div.
我们将chrome.tabs.executeScript()
在browserAction
单击处理程序中使用内容脚本文件(或文字代码字符串,如果它很小,请参阅方法的文档)到该页面的DOM.
var someVar = {text: 'test', foo: 1, bar: false};
chrome.tabs.executeScript({
code: '(' + function(params) {
document.body.insertAdjacentHTML('beforeend',
'<div style="all:unset; position:fixed; left:0; top:0; right:0; bottom:0;' +
'background-color:rgba(0,255,0,0.3)">' + params.text + '</div>'
);
return {success: true, html: document.body.innerHTML};
} + ')(' + JSON.stringify(someVar) + ');'
}, function(results) {
console.log(results[0]);
});
Run Code Online (Sandbox Code Playgroud)
如您所见,我们使用了函数代码的自动字符串转换,以便能够将注入的代码编写为具有语法高亮和linting的普通JavaScript.显而易见的缺点是浏览器浪费时间来解析代码,但通常它不到1毫秒,因此可以忽略不计.
wOx*_*xOm 13
使用编程注入来添加该 div 的扩展弹出脚本的一些示例。
不要忘记在 manifest.json 中添加权限,请参阅其他答案以获取更多信息。
简单的调用:
(async () => {
const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
const [{result}] = await chrome.scripting.executeScript({
target: {tabId: tab.id},
func: () => document.querySelector('foo')?.textContent,
});
document.body.textContent = result;
})();
Run Code Online (Sandbox Code Playgroud)
简单调用2:
(async () => {
const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
await chrome.scripting.executeScript({
target: {tabId: tab.id},
func: inContent1,
});
})();
// executeScript runs this code inside the tab
function inContent1() {
const el = document.createElement('div');
el.style.cssText = 'position:fixed; top:0; left:0; right:0; background:red';
el.textContent = 'DIV';
document.body.appendChild(el);
}
Run Code Online (Sandbox Code Playgroud)
注意:在 Chrome 91 或更早版本中func:
应该是function:
.
带参数调用并接收结果
需要 Chrome 92 来实现args
。
示例1:
res = await chrome.scripting.executeScript({
target: {tabId: tab.id},
func: (a, b) => { return [window[a], window[b]]; },
args: ['foo', 'bar'],
});
Run Code Online (Sandbox Code Playgroud)
示例2:
(async () => {
const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
let res;
try {
res = await chrome.scripting.executeScript({
target: {tabId: tab.id},
func: inContent2,
args: [{ foo: 'bar' }], // arguments must be JSON-serializable
});
} catch (e) {
console.warn(e.message || e);
return;
}
// res[0] contains results for the main page of the tab
document.body.textContent = JSON.stringify(res[0].result);
})();
// executeScript runs this code inside the tab
function inContent2(params) {
const el = document.createElement('div');
el.style.cssText = 'position:fixed; top:0; left:0; right:0; background:red';
el.textContent = params.foo;
document.body.appendChild(el);
return {
success: true,
html: document.body.innerHTML,
};
}
Run Code Online (Sandbox Code Playgroud)
简单的调用:
// uses inContent1 from ManifestV3 example above
chrome.tabs.executeScript({ code: `(${ inContent1 })()` });
Run Code Online (Sandbox Code Playgroud)
带参数调用并接收结果:
// uses inContent2 from ManifestV3 example above
chrome.tabs.executeScript({
code: `(${ inContent2 })(${ JSON.stringify({ foo: 'bar' }) })`
}, ([result] = []) => {
if (!chrome.runtime.lastError) {
console.log(result); // shown in devtools of the popup window
}
});
Run Code Online (Sandbox Code Playgroud)
此示例使用inContent
函数代码自动转换为字符串,这样做的好处是 IDE 可以应用语法高亮和 linting。明显的缺点是浏览器会浪费时间来解析代码,但通常不到 1 毫秒,因此可以忽略不计。
归档时间: |
|
查看次数: |
50018 次 |
最近记录: |