实现跨扩展消息传递在chrome扩展和应用程序

Implement cross extension message passing in chrome extension and app

本文关键字:扩展 应用程序 chrome 消息传递 实现      更新时间:2023-09-26

我正试图根据这篇文章做chrome扩展和chrome应用程序之间的交叉扩展消息传递。但我不确定如何正确地做它。我使用后台js来接收和发送消息。但不知道它是否有效。实际上我想保存文件从chrome扩展,因为它不能做到我认为这可以工作。所以任何想法、建议或例子都是非常欢迎的。

就像这个问题一样,我已经考虑了很多选择。其中一个答案指出了这个例子。我发现这个例子工作得很好。我希望我可以使用这种机制来保存文件使用Chrome应用程序的文件系统API。

Chrome消息传递api只能传输json序列化值。如果文件很小,那么你可以在扩展中使用FileReader读取文件内容,通过外部消息传递通道发送消息到Chrome应用程序,然后使用FileWriter API保存数据。

当文件较大时,使用file.slice(start, end)分块读取文件,然后使用与小文件相同的方法。

扩展:

var app_id = '.... ID of app (32 lowercase a-p characters) ....';
var file = ...; // File or Blob object, e.g. from an <input type=file>
var fr = new FileReader();
fr.onload = function() {
    var message = {
        blob: fr.result,
        filename: file.name,
        filetype: file.type
    };
    chrome.runtime.sendMessage(app_id, message, function(result) {
        if (chrome.runtime.lastError) {
            // Handle error, e.g. app not installed
            console.warn('Error: ' + chrome.runtime.lastError.message);
        } else {
            // Handle success
            console.log('Reply from app: ', result);
        }
    });
};
fr.onerror = function() { /* handle error */ };
// file or sliced file.
fr.readAsText(file);

应用程序:

chrome.runtime.onMessageExternal.addListener(
  function(message, sender, sendResponse) {
    // TODO: Validate that sender.id is allowed to invoke the app!
    // Do something, e.g. convert back to Blob and do whatever you want.
    var blob = new Blob([message.blob], {type: message.filetype});
    console.log('TODO: Do something with ' + message.filename + ':', blob);
    // Do something, e.g. reply to message
    sendResponse('Processed file');
    // if you want to send a reply asynchronously, uncomment the next line.
    // return true;
});

编辑:虽然下面的方法在理论上听起来不错,但它在实践中不起作用,因为为应用程序/扩展创建了一个单独的SharedWorker进程。

如果您想发送大文件(例如File s),那么您可以实现以下操作:

  1. 扩展:创建proxy.html (content = <script src=proxy.js></script>)。(请随意选择其他名称)。
  2. 扩展:Put proxy.html in web_accessible_resources .
  3. App:绑定window.onmessage事件监听器这个事件监听器将接收来自你要在下一步中加载的帧的消息。
  4. App:加载chrome-extension://[EXTENSIONID]/proxy.html在你的应用程序内的一个框架。这个扩展ID可以硬编码(参见获取Chrome扩展ID开发)或通过外部扩展消息传递API交换(确保你验证源-硬编码ID将是最好的方式)。
  5. 扩展:当proxy.html加载时,检查location.ancestorOrigins[0] == 'chrome-extension://[APPID]'是否加载,以避免安全漏洞。
  6. 扩展:当你想传递一个FileBlob的应用程序,使用parent.postMessage(blob, 'chrome-extension://[APPID]');
  7. App:当它从扩展帧接收blob时,将其保存到通过chrome.fileSystem API获得的文件系统中。

最后一个要解决的任务是从扩展到扩展框架(proxy.html)的文件,该扩展框架嵌入在应用程序中。这可以通过SharedWorker完成,参见此示例答案(您可以跳过创建新框架的部分,因为扩展框架已经在前面的步骤之一中创建)。
请注意,目前(Chrome 35), File s只能发送一个工作,由于一个错误。