我正在开发一个Chrome扩展程序,需要我的内容脚本来访问网页的所有框架,以便检测某些特定字段。
一旦检测到,我将尝试将该字段元素存储在全局对象中其各自的属性中。问题是,如果元素都位于不同的 iframe 中,则每个元素都会获得该脚本的副本并填充自己的对象副本,而不是单个全局对象。
有没有办法让对象的一个全局实例并在每次检测到字段时将值附加到其属性?
例如:
原始对象
{
userName: [],
email: []
}
在 iframe1 中检测到用户名字段
{
userName: [<input id="username">...</input>],
email: []
}
在 iframe2 中检测到电子邮件字段
{
userName: [],
email: [<input id="email">...</input>]
}
期望的结果
{
userName: [<input id="username">...</input>],
email: [<input id="email">...</input>]
}
通过扩展消息传递到后台脚本来组织通信会更加安全可靠。内容脚本的实例在主页和所有 iframe 中运行,主脚本等待数据,框架中的其他实例通过后台页面中继发送数据。
内容脚本:
if (window === top) {
// main page
const data = {};
chrome.runtime.onMessage.addListener(msg => {
Object.assign(data, msg.data);
if (data.email && data.username) {
console.log('Got both values', data);
}
});
} else {
// inside a frame
const data = {};
for (const id of ['username', 'email']) {
const el = document.getElementById(id);
if (el) data[id] = el.value;
}
if (Object.keys(data).length)
chrome.runtime.sendMessage({data});
}
后台脚本:
chrome.runtime.onMessage.addListener((msg, sender) => {
// message from a frame?
if (msg.data && sender.frameId) {
// relay it to the main page (frameId: 0)
chrome.tabs.sendMessage(sender.tab.id, msg, {frameId: 0});
}
});