从内容脚本访问后台脚本对象
Accessing background script object from content script
如何在chrome扩展内访问背景脚本对象形成内容脚本?
在内容脚本我有:
// this will store settings
var settings = {};
// load settings from background
chrome.extension.sendMessage({
name: "get-settings"
}, function(response) {
debugger;
settings = response.data.settings;
});
在背景脚本中,我有:
var Settings = function() {
var me = this;
// internal, default
var settingList = {
serverUrl : "http://automatyka-pl.p4",
isRecordingEnabled : true,
isScanEnabled : true
};
this.get = function( key ) {
return settingList[key];
};
this.set = function( key , value ) {
if (settingList[key] != value) {
var setting = {};
setting[key] = value;
chrome.storage.sync.set(setting, function() {
settingList[key] = value;
});
}
return true;
};
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
if (request.name == 'get-settings') {
sendResponse({
data : {
settings : settings
}
});
return true;
}
});
var settings = new Settings();
消息传递工作,我的意思是响应是发送,但返回的对象是空的。你知道怎么解吗?
编辑根据你的评论和回答,我将尝试为我的问题增添不同的亮点。
实际问题是:如何从内容脚本中访问后台"model".
让我们假设内容脚本持续响应页面DOM更改。每当检测到更改时,都会在内容脚本中进行一些处理。但是这种处理取决于扩展设置。这些设置可以通过动作弹出脚本来设置,该脚本通知背景模型这些设置是什么。所以,任何时候用内容脚本处理页面,它应该知道背景脚本中存储的当前设置。
如前所述,从后台提取设置是一个异步过程,所以我需要一个回调来进一步处理内容脚本。进一步的处理必须等待设置(所以应该同步处理?)。
我很难想象在这种情况下程序流应该是什么样子。
- 后台负载(设置初始化)
- 页面加载->内容脚本加载
- 内容脚本请求设置->进一步的处理在回调函数中完成。
- 用户更改设置,后台设置更改 触发
- 页面更改,内容脚本响应
- 内容脚本请求设置->进一步的处理是在回调函数内完成-但它不能是相同的功能,如在pt. 3(内容"模型"不必初始化)?
-
sendMessage不传输对象本身,而只传输对象的json表示。实际上是
objReceived = JSON.parse(JSON.stringify(objSent))
,所以因为对象的settingList
在函数上下文之外是不可见的,它在序列化期间丢失了。你可以通过暴露一个可字符串化的属性
使它成为公共的this.settingList = { foo: 'bar' };
-
由于消息传递是异步的,要在内容脚本中使用响应,您应该在响应回调中执行:
// this will store the settings var settings = {}; // load settings from background chrome.runtime.sendMessage({ name: "get-settings" }, function(response) { settings = response.data.settings; onSettingsReady(); }); function onSettingsReady() { // put your logic here, settings are set at this point }
-
要知道设置是否在你的content-script之外被更改,在background.js中的settings setter中发送消息到你的选项卡的content-script:
this.set = function( key , value ) { ... // notify active tab if settings changed chrome.tabs.query({"windowType":"normal"}, function(tabs){ for( id in tabs ){ if("id" in tabs[id]){ chrome.tabs.sendMessage(tabs[id].id,{"action":"update-settings","settings":settings}); } } }); return true; };
-
在content-script中监听并处理以下消息:
chrome.runtime.onMessage.addListener(function(msg){ if("action" in msg && msg.action == 'update-settings'){ // You are setting global settings variable, so on it will be visible in another functions too settings = msg.settings; } });
详细信息:https://developer.chrome.com/extensions/runtime#method-sendMessage.
注:使用chrome.runtime.sendMessage
代替chrome.extension.sendMessage
,因为后者在Chrome API中已弃用,并且在webeextensions API (Firefox/Edge)中完全不支持。
在您的内容脚本中添加另一个Settings
实例可能会更有意义。
毕竟chrome.storage
API在内容脚本中是可用的。
当然,你需要观察扩展的其他部分所做的变化-但你应该这样做,因为你使用chrome.storage.sync
和它的值可以通过Chrome同步独立更改。
所以,建议的解决方案:
- 为
chrome.storage.onChanged
添加一个监听器,并根据需要处理settingList
的更改。 - 将
Storage
逻辑移动到单独的JS"库"中,例如storage.js
- 在你的内容脚本中加载
storage.js
并正常使用。
你可能还想调整你的存储逻辑,这样保存的数据实际上是考虑在内-现在它总是默认的。你可以这样做:
var defaultSettingList = {
serverUrl : "http://automatyka-pl.p4",
isRecordingEnabled : true,
isScanEnabled : true
};
var settingList = Object.assign({}, defaultSettingList);
chrome.storage.sync.get(defaultSettingList, function(data) {
settingList = Object.assign(settingList, data);
// At this point you probably should call the "ready" callback - initial
// load has to be async, no way around it
});
- 选项卡侦听器未被来自后台脚本的消息激活
- 将图像从后台页面传递给内容脚本javascript
- 使用javascript后台脚本获取Yotutube频道信息
- 在chrome web商店中打开时,是否有允许执行内容/后台脚本的解决方案
- 在后台运行的脚本在出现弹出窗口时会停止
- 在chrome扩展中获取从后台页面到内容脚本的配置
- 使用chrome扩展,如何使用长寿命连接(端口)将消息从后台脚本传递到内容脚本
- Chrome扩展使用后台页面+内容脚本
- Chrome扩展:在后台页面和网站页面脚本之间进行通信的最佳方法
- 为什么chrome.sockets.tcp.create()在应用程序后台脚本中不起作用
- Chrome 打包应用 - 消息从后台传递.js传递到另一个脚本页面
- 将注入的按钮从内容脚本调用到后台.js
- 后台脚本在受限范围内运行的 Chrome 应用
- 如何停止 npm 脚本在后台自动运行
- 如何通过在后台运行安装程序或脚本来安装 NPAPI 插件
- Chrome:同时使用内容和后台脚本不起作用
- 从“选项”弹出窗口中选择一个值,然后将其保存到 Chrome.storage,以便在后台脚本中用作值
- 应用程序后台脚本,访问打开的窗口的元素
- Chrome 扩展程序:无法让消息传递在后台脚本和内容脚本之间正常工作
- 如何在后台获取 chrome 扩展程序的内容脚本