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;
});
编辑:尽管使用以下方法在理论上听起来不错,但它在实践中不起作用,因为为应用程序/扩展创建了一个单独的 SharedWorker 进程。
如果你想发送大文件(例如Files),那么你可以实现以下:
- 扩展:创建
proxy.html(内容=<script src=proxy.js></script>)。 (随意选择其他名称)。
- 分机:将
proxy.html 放入web_accessible_resources。
- App:绑定一个
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]');
- App:当它从扩展框架接收到blob时,将其保存到您通过
chrome.fileSystem API获取的FileSystem中。
最后要解决的任务是从扩展中获取文件到嵌入在应用程序中的扩展框架 (proxy.html)。这可以通过SharedWorker 来完成,请参见this answer 示例(您可以跳过创建新框架的部分,因为扩展框架已经在前面的步骤之一中创建)。
请注意,目前 (Chrome 35),Files can only be sent with a work-around due to a bug。