【问题标题】:Chrome Extension Background Page and Content Script SynchronizationChrome 扩展后台页面和内容脚本同步
【发布时间】:2015-06-21 18:05:21
【问题描述】:

假设我的 Chrome 扩展程序的后台页面中有以下代码。

var opts;
chrome.storage.local.get(options, function(result) {
    opts = result[options];
});

chrome.runtime.onMessage.addListener(function(request, sender, response) {
    if (request.message === 'getOpts')
        response(opts);
});

在我的内容脚本中,我通过消息传递访问opts

chrome.runtime.sendMessage({'message': 'getOpts'}, function(response) {
    console.log(opts);
});

是否可以保证在内容脚本运行之前定义选项?例如,在启动浏览器时,后台页面会运行,想必对chrome.storage.local.get的回调会被添加到后台页面的消息队列中。 Chrome 会在注入内容脚本之前完成该队列的处理吗?

我可以从内容脚本中调用 chrome.storage.local.get,但我的问题更笼统,因为我的后台页面中有额外的异步处理。目前,我的内容脚本会检查后台页面以确保一切就绪(使用间隔继续检查),但我不确定是否有必要进行此类检查。

【问题讨论】:

  • 然后向我们展示您传递的信息。否则很难回答。
  • 嗨,Xan,我添加了显示消息传递的代码。
  • 似乎无法保证。即使 Chrome 在加载内容脚本之前处理了后台脚本队列中的所有消息,在后台脚本运行完成时,对 chrome.storage.local.get 的回调可能还没有在队列中。跨度>

标签: javascript google-chrome-extension


【解决方案1】:

您实际上可以异步回复消息。

chrome.runtime.onMessage.addListener(function(request, sender, response) {
  if (request.message === 'getOpts') {
    chrome.storage.local.get('options', function(result) {
      response(result[options]);
    });
    return true; // Indicate that response() will be called asynchronously
  }
});

chrome.storage 的情况下,这确实是愚蠢的,因为 API 专门设计用于解决在内容脚本中使用 localStorage + 消息传递的迂回性质;您可以直接从内容脚本中查询。

但在异步处理的一般情况下,您可以推迟对消息的回复。你只需要从监听器返回一个真值来表明你还没有完成。

【讨论】:

  • 嗨,Xan,感谢您的回复。我也可以直接从我的内容脚本中调用 chrome.storage.local.get。但是,我的问题更笼统。我想知道是否可以保证在注入内容脚本之前定义 opts。
  • 内容脚本不会在扩展加载时注入。您必须在加载扩展后实际导航以获得内容脚本。所以通常有很大的时间余量。
  • 我在帖子中特别使用了浏览器启动示例来解决该问题。 (因为在浏览器启动时会加载后台页面,内容脚本也是如此)。
  • 是的,我也想过那个案子。我不知道是否有任何保证。这是一个有趣的问题,它在浏览器启动时是如何工作的。我会提出一个单独的具体问题,它可能需要有 Chrome 内部经验的人回答,比如 RobW。
  • 我的意思是,我明白你的意思。 addListener 是否保证在发送消息之前运行?
【解决方案2】:

不要依赖定义的变量,即使它在您的测试中。一般来说,由于正常的时间安排,你的 var 应该在它收到消息的时候设置,但是为了确保你应该在你的后台 onMessage 中检查。我已经通过在全局中记住我是否已经初始化了扩展并且如果需要从 onMessage 中这样做来处理这个问题。 xan 的回答显示了在这种情况下如何在异步初始化完成后使用“return true”来处理消息。

my chrome extension 上查看此示例(搜索bCalled

你可以看到我有一个 sendResponse 方法负责检测回调是否已被调用,如果没有,则返回 true(假设异步操作正在进行中,稍后将调用回调)

您还可以通过在加载该变量的后台代码中假装延迟来进行试验和测试。

【讨论】:

  • 您好 Zig,感谢您的回复。我已经有代码可以检查一切是否准备就绪,并相应地进行。我很好奇这样的代码是否必要,我将您的帖子解释为建议检查是必要的。
  • 今天可能需要也可能不需要,但最好为将来或不可预见的情况添加它。
猜你喜欢
  • 1970-01-01
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-09
  • 2011-09-28
  • 2015-04-23
相关资源
最近更新 更多