我正在尝试根据this article在Chrome扩展程序和Chrome应用程序之间传递交叉扩展消息。但我不确定如何正确地做到这一点。我使用后台js来接收和发送消息。但不知道它是否有效。实际上我想从chrome扩展中保存文件,因为它无法完成我认为这可行。所以任何想法,建议或例子都非常受欢迎。
我在this question中也有许多替代品。然后回答这个例子之一。我发现this example工作正常。我希望我可以使用此机制使用Chrome App的fileSystem API保存文件。
答案 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
),那么你可以实现以下内容:
proxy.html
(内容= <script src=proxy.js></script>
)。 (随意选择任何其他名称)。proxy.html
放入web_accessible_resources
。window.onmessage
事件监听器。此事件侦听器将从您将在下一步中加载的帧中接收消息。chrome-extension://[EXTENSIONID]/proxy.html
。此扩展ID可以是硬编码的(请参阅Obtaining Chrome Extension ID for development),也可以通过外部扩展消息传递API进行交换(确保您验证源代码 - 硬编码ID将是最佳方式)。proxy.html
时,请检查location.ancestorOrigins[0] == 'chrome-extension://[APPID]'
是否存在安全漏洞。如果此条件失败,请终止所有步骤。File
或Blob
传递给该应用,请使用parent.postMessage(blob, 'chrome-extension://[APPID]');
chrome.fileSystem
API获取的文件系统。 要解决的最后一项任务是将文件从扩展程序获取到应用程序中嵌入的扩展程序框架( proxy.html
)。这可以通过SharedWorker
来完成,有关示例,请参阅this answer(您可以跳过创建新框架的部分,因为扩展框架已在前面的步骤之一中创建)。
请注意,目前(Chrome 35),File
s can only be sent with a work-around due to a bug。