Javascript 从内容脚本访问背景脚本对象

Javascript 从内容脚本访问背景脚本对象,javascript,google-chrome,google-chrome-extension,Javascript,Google Chrome,Google Chrome Extension,如何在chrome扩展中访问背景脚本对象形成内容脚本 在内容脚本中,我有: // this will store settings var settings = {}; // load settings from background chrome.extension.sendMessage({ name: "get-settings" }, function(response) { debugger; s

如何在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();
在背景脚本中,我有:

    // 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();
消息传递工作,我的意思是响应是发送的,但返回的对象是空的。你知道怎么解决这个问题吗

编辑 根据您的评论和回答,我将尝试为我的问题添加不同的光

实际问题是: 如何从内容脚本访问后台“模型”

让我们假设内容脚本持续响应页面DOM更改。检测到任何更改时,都会在内容脚本中进行一些处理。但此处理取决于扩展设置。这些设置可以通过页面操作弹出脚本进行设置,该脚本通知后台模型这些设置是什么

因此,每当使用内容脚本处理页面时,它都应该知道存储在后台脚本中的当前设置

如前所述,从后台提取设置是一个异步过程,因此我需要一个回调,以便在内容脚本中进行进一步处理。进一步的处理必须等待设置(所以应该同步处理吗?)

我很难想象在这种情况下程序流应该是什么样子

  • 后台加载(设置已初始化)
  • 页面加载->内容脚本加载
  • 内容脚本请求设置->进一步处理在回调函数内完成
  • 用户更改设置,背景设置更改
  • 页面更改被触发,内容脚本响应
  • 内容脚本请求设置->进一步处理在回调函数内完成-但它不能与pt中的函数相同。3(内容“模型”不必初始化)
  • sendMessage不传输对象本身,只传输其JSON ifiable表示形式, 实际上,由于对象的
    设置列表
    在函数上下文之外是不可见的,因此在序列化过程中它会丢失

    您可以通过公开stringifiable属性将其公开

    this.settingList={foo:'bar'};
    
    这将成功地传输到您的内容脚本

  • 由于消息传递非常重要,要在内容脚本中使用响应,应在响应回调中执行:

    //这将存储设置
    变量设置={};
    //从后台加载设置
    chrome.runtime.sendMessage({
    名称:“获取设置”
    },功能(回应){
    设置=response.data.settings;
    onSettingsReady();
    }); 
    函数onSettingsReady(){
    //把你的逻辑放在这里,设置在这一点上
    }
    
  • 要了解设置是否在内容脚本之外更改,请在background.js的settings setter中向选项卡的内容脚本发送消息:

    this.set=函数(键、值){
    ...
    //设置更改时通知活动选项卡
    chrome.tabs.query({“windowType”:“normal”},函数(tabs){
    用于(选项卡中的id){
    如果选项卡[id]中的“id”){
    chrome.tabs.sendMessage(tabs[id].id,{“操作”:“更新设置”,“设置”:设置});
    }
    }
    });
    返回true;
    };
    
  • 在内容脚本中,听并处理此消息:

    chrome.runtime.onMessage.addListener(函数(msg)){
    如果消息中的“操作”&&msg.action==“更新设置”){
    //您正在设置全局设置变量,因此在其他函数中也可以看到该变量
    设置=msg.settings;
    }
    });
    
  • 更多详细信息:

    另外,请使用
    chrome.runtime.sendMessage
    而不是
    chrome.extension.sendMessage
    ,因为后者在chrome API中不受欢迎,在WebExtensions API(Firefox/Edge)中完全不受支持

  • sendMessage不传输对象本身,只传输其JSON ifiable表示形式, 实际上,由于对象的
    设置列表
    在函数上下文之外是不可见的,因此在序列化过程中它会丢失

    您可以通过公开stringifiable属性将其公开

    this.settingList={foo:'bar'};
    
    这将成功地传输到您的内容脚本

  • 由于消息传递非常重要,要在内容脚本中使用响应,应在响应回调中执行:

    //这将存储设置
    变量设置={};
    //从后台加载设置
    chrome.runtime.sendMessage({
    名称:“获取设置”
    },功能(回应){
    设置=response.data.settings;
    onSettingsReady();
    }); 
    函数onSettingsReady(){
    //把你的逻辑放在这里,设置在这一点上
    }
    
  • 要了解设置是否在内容脚本之外更改,请在background.js的settings setter中向选项卡的内容脚本发送消息:

    this.set=函数(键、值){
    ...
    //设置更改时通知活动选项卡
    chrome.tabs.query({“windowType”:“normal”},函数(tabs){
    用于(选项卡中的id){
    如果选项卡[id]中的“id”){
    chrome.tabs.sendMessage(tabs[id].id,{“操作”:“更新设置”,“设置”:设置});
    }
    }
    });
    返回true;
    };
    
  • 在内容脚本中,听并处理此消息:

    chrome.runtime.onMessage.addListener(函数(msg)){
    如果消息中的“操作”&&msg.action==“更新设置”){
    //您正在设置全局设置变量,因此在其他函数中也可以看到该变量
    设置=msg.settings;
    }
    });
    
  • 更多详细信息:


    另外,请使用
    chrome.runtime.sendMessage
    而不是
    chrome.extension.sendMessage
    ,因为后者在chrome API中不受欢迎,在WebExtensions API(Firefox/Edge)中完全不受支持。

    在内容脚本中使用另一个
    设置实例可能更有意义

    毕竟,
    chrome.storage
    API在内容脚本中是可用的。