应用开发几乎方方面面都涉及到发送或接收数据的一些元素。正在启动 您应使用 MVC 框架帮助您设计和实现应用,以便 与此数据的应用视图完全无关(请参阅MVC 架构)。
您还需要考虑应用离线时数据的处理方式(请参阅离线优先)。 本文档简要介绍了用于在本地发送、接收和保存数据的存储选项;该 本文档的其余部分介绍了如何使用 Chrome 的 File System API 和 Sync File System API(另请参阅 fileSystem API 和 syncFileSystem API)。
存储选项
打包应用程序使用许多不同的机制来发送和接收数据。对于外部数据(资源、 网页),您需要了解内容安全政策 (CSP)。与 Chrome 类似 扩展程序,您可以使用跨源 XMLHttpRequests 与远程服务器进行通信。您 您还可以隔离外部页面,以确保应用的其余部分安全无虞(请参阅嵌入外部网页 页)。
在本地保存数据时,您可以使用 Chrome Storage API 保存少量字符串 和 IndexedDB 来保存结构化数据。借助 IndexedDB,您可以将 JavaScript 对象保留在 对象存储并使用存储的索引来查询数据(要了解详情,请参见 HTML5 Rock 的简单待办事项 列出教程)。对于所有其他类型的数据(例如二进制数据),请使用“文件系统和同步” 文件系统 API。
Chrome 的 Filesystem API 和 Sync Filesystem API 扩展了 HTML5 FileSystem API。通过 Chrome 的 Filesystem API,因此应用可以创建、读取、浏览和写入用户 本地文件系统例如,照片分享应用可以使用 Filesystem API 读取和写入任何 用户选择的照片。
借助 Chrome 的 Sync Filesystem API,应用可以保存和同步用户的 Google 云端硬盘中的数据, 确保不同的客户端可以提供相同的数据。例如,基于云计算的文本 编辑器应用可将新的文本文件自动同步到用户的 Google 云端硬盘账号。当 用户在新客户端中打开文本编辑器,Google 云端硬盘会将新文本文件推送到 文本编辑器。
使用 Chrome Filesystem API
正在添加文件系统权限
要使用 Chrome 的 File System API,您需将“fileSystem”对清单的权限 您可从用户处获取存储持久性数据的权限。
"permissions": [
"...",
"fileSystem"
]
用于选择文件的用户选项
用户希望以相同的方式选择文件。他们至少希望“选择” file'按钮和标准的文件选择器。如果您的应用大量使用文件处理功能,您还应该 实现拖放(请参阅下文,另请参阅原生 HTML5 拖放)。
获取 fileEntry 的路径
如需获取用户所选文件 fileEntry
的完整路径,请调用 getDisplayPath()
:
function displayPath(fileEntry) {
chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
console.log(path)
});
}
实现拖放
如果您需要实现拖放选择功能,可使用以下代码中的拖放文件控制器 (dnd.js
)
不妨从 filesystem-access 示例入手。控制器会创建一个文件条目
从 DataTransferItem
添加。在此示例中,fileEntry
设置为第一个
已放下内容。
var dnd = new DnDFileController('body', function(data) {
var fileEntry = data.items[0].webkitGetAsEntry();
displayPath(fileEntry);
});
读取文件
以下代码会打开该文件(只读),并使用 FileReader
对象以文本形式读取该文件。如果
如果文件不存在,系统会抛出错误。
var chosenFileEntry = null;
chooseFileButton.addEventListener('click', function(e) {
chrome.fileSystem.chooseEntry({type: 'openFile'}, function(readOnlyEntry) {
readOnlyEntry.file(function(file) {
var reader = new FileReader();
reader.onerror = errorHandler;
reader.onloadend = function(e) {
console.log(e.target.result);
};
reader.readAsText(file);
});
});
});
写入文件
写入文件的两种常见用例是“保存”和“另存为”以下代码会创建一个
来自只读 chosenFileEntry
的 writableEntry
,并将所选文件写入其中。
chrome.fileSystem.getWritableEntry(chosenFileEntry, function(writableFileEntry) {
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = callback;
chosenFileEntry.file(function(file) {
writer.write(file);
});
}, errorHandler);
});
以下代码将使用“另存为”选项创建一个新文件功能,并将新的 blob 写入
使用 writer.write()
方法保存该文件。
chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = function(e) {
console.log('write complete');
};
writer.write(new Blob(['1234567890'], {type: 'text/plain'}));
}, errorHandler);
});
使用 Chrome Sync Filesystem API
使用可同步的文件存储,可以采用与本地操作相同的方式操作返回的数据对象 FileSystem API 中的离线文件系统,但增加了(自动)同步该系统的功能 将数据导出到 Google 云端硬盘
添加同步文件系统权限
要使用 Chrome 的 Sync Filesystem API,您需将“syncFileSystem”对 以便从用户处获取存储和同步持久性数据的权限。
"permissions": [
"...",
"syncFileSystem"
]
正在启动可同步的文件存储
要在您的应用中启动可同步的文件存储,只需调用 syncFileSystem.requestFileSystem 即可。 此方法会返回 Google 云端硬盘支持的可同步文件系统,例如:
chrome.syncFileSystem.requestFileSystem(function (fs) {
// FileSystem API should just work on the returned 'fs'.
fs.root.getFile('test.txt', {create:true}, getEntryCallback, errorCallback);
});
关于文件同步状态
使用 syncFileSystem.getFileStatus 可获取当前文件的同步状态:
chrome.syncFileSystem.getFileStatus(entry, function(status) {...});
文件同步状态值可以是以下值之一:'synced'
、'pending'
或 'conflicting'
。
“已同步”表示文件已完全同步;您没有尚未完成的待更改本地更改
已同步到 Google 云端硬盘。不过,Google 云端硬盘中可能会有一些待更改项
尚未提取。
“待处理”表示文件中有尚未同步到 Google 云端硬盘的待更改项。如果应用
在线运行时,本地更改(几乎)会立即同步到 Google 云端硬盘,而
系统会以 'synced'
状态触发 syncFileSystem.onFileStatusChanged 事件(请参阅下文
)。
当文件的状态变为syncFileSystem.onFileStatusChanged
'conflicting'
。“冲突”意味着本地存储空间和本地存储空间中
Google 云端硬盘。仅当冲突解决政策设置为
'manual'
。默认政策为 'last_write_win'
,冲突会自动解决
简单的“最后写胜”政策可以通过以下方式更改系统的冲突解决政策:
syncFileSystem.setConflictResolutionPolicy.
如果冲突解决政策设为 'manual'
且文件导致 'conflicting'
状态,
应用仍然可以将文件作为本地离线文件读取和写入,但是更改不会同步
并且文件将与在其他客户端上进行的远程更改取消关联,直到冲突
已解决。解决冲突的最简单方法是删除或重命名文件的本地版本。
这会强制同步远程版本,冲突状态得到解决,
系统会以 'synced'
状态触发 onFileStatusChanged
事件。
监听同步状态的变化
当文件的同步状态更改时,会触发 syncFileSystem.onFileStatusChanged 事件。
例如,假设某个文件有待更改项,且处于“待处理”状态。状态。该应用可能
处于脱机状态,以便可以同步更改。当同步服务检测到
本地更改,并将更改上传到 Google 云端硬盘时,该服务会触发
具有以下值的 onFileStatusChanged
事件:
{ fileEntry:a fileEntry for the file, status: 'synced', action: 'updated', direction: 'local_to_remote' }
。
同样,无论本地活动如何,同步服务都可能会检测到
另一个客户端,并将更改从 Google 云端硬盘下载到本地存储空间。如果遥控器
就会触发具有以下值的事件:
{ fileEntry: a fileEntry for the file, status: 'synced', action: 'added', direction: 'remote_to_local' }
。
如果本地端和远程端对同一文件的更改存在冲突,并且
分辨率政策设为'manual'
,文件状态已更改为conflicting
状态,
与同步服务分离,并且在冲突解决之前不会进行同步。在本课中,
就会触发具有以下值的事件:
{ fileEntry: a fileEntry for the file, status: 'conflicting', action: null, direction: null }
。
您可以为此事件添加监听器,以响应任何状态变化。例如, Chrome 音乐播放器应用可收听从 Google 云端硬盘同步过来但尚未播放的任何新音乐 用户本地存储空间中的内容。找到的所有音乐都会同步到该设备 客户:
chrome.syncFileSystem.onFileStatusChanged.addListener(function(fileInfo) {
if (fileInfo.status === 'synced') {
if (fileInfo.direction === 'remote_to_local') {
if (fileInfo.action === 'added') {
db.add(fileInfo.fileEntry);
} else if (fileInfo.action === 'deleted') {
db.remove(fileInfo.fileEntry);
}
}
}
});
检查 API 使用情况
要检查 API 使用的数据量,请查询应用的本地沙盒化目录或 syncFileSystem.getUsageAndQuota 返回的用量字节数:
chrome.syncFileSystem.getUsageAndQuota(fileSystem, function (storageInfo) {
updateUsageInfo(storageInfo.usageBytes);
updateQuotaInfo(storageInfo.quotaBytes);
});
您还可以查看用户的同步后端服务存储空间(位于 Google 云端硬盘中)。已同步的文件 保存在隐藏的 Google 云端硬盘文件夹 Chrome Syncable FileSystem。该文件夹不会显示在 您的“我的云端硬盘”但也可通过在搜索框中搜索文件夹名称来访问。(请注意, 不保证远程文件夹布局在各版本之间保持向后兼容。)