实现Chrome扩展程序和应用程序中的交叉扩展消息传递

时间:2014-07-05 02:59:30

标签: javascript google-chrome google-chrome-extension messaging google-chrome-app

我正在尝试根据this article在Chrome扩展程序和Chrome应用程序之间传递交叉扩展消息。但我不确定如何正确地做到这一点。我使用后台js来接收和发送消息。但不知道它是否有效。实际上我想从chrome扩展中保存文件,因为它无法完成我认为这可行。所以任何想法,建议或例子都非常受欢迎。

我在this question中也有许多替代品。然后回答这个例子之一。我发现this example工作正常。我希望我可以使用此机制使用Chrome App的fileSystem API保存文件。

1 个答案:

答案 0 :(得分:1)

Chrome消息传递API只能传输JSON可序列化的值。如果文件很小,那么您只需使用扩展程序中的FileReader读取文件内容,通过外部消息传递渠道将消息发送到Chrome应用,然后save the data using the 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;
});

编辑:虽然以下方法在理论上使用听起来不错,但在实践中不起作用,因为为app / extension创建了单独的SharedWorker进程。

如果你想发送大文件(例如File),那么你可以实现以下内容:

  1. 扩展程序:创建proxy.html(内容= <script src=proxy.js></script>)。 (随意选择任何其他名称)。
  2. 扩展名:将proxy.html放入web_accessible_resources
  3. 应用:绑定window.onmessage事件监听器。此事件侦听器将从您将在下一步中加载的帧中接收消息。
  4. 应用:在应用内的框架中加载chrome-extension://[EXTENSIONID]/proxy.html。此扩展ID可以是硬编码的(请参阅Obtaining Chrome Extension ID for development,也可以通过外部扩展消息传递API进行交换(确保您验证源代码 - 硬编码ID将是最佳方式)。
  5. 扩展:加载proxy.html时,请检查location.ancestorOrigins[0] == 'chrome-extension://[APPID]'是否存在安全漏洞。如果此条件失败,请终止所有步骤。
  6. 扩展名:如果您想将FileBlob传递给该应用,请使用parent.postMessage(blob, 'chrome-extension://[APPID]');
  7. 应用:当它从扩展帧接收blob时,将其保存到您通过chrome.fileSystem API获取的文件系统。
  8. 要解决的最后一项任务是将文件从扩展程序获取到应用程序中嵌入的扩展程序框架(proxy.html)。这可以通过SharedWorker来完成,有关示例,请参阅this answer(您可以跳过创建新框架的部分,因为扩展框架已在前面的步骤之一中创建)。
    请注意,目前(Chrome 35),Files can only be sent with a work-around due to a bug