❗ 本文最后更新于 4068 天前,文中所描述的信息可能已发生改变,请谨慎使用。
上篇文章讲到如何用 JavaScript 编写下载器,不少小伙伴看了觉得神奇。在本篇文章里,我把之前写的一个 JS 游戏全部资源打成 Zip 包,用上回写的下载器加载,再解压到 FileSystem,最后直接运行这个游戏。也就是说只需要一次 HTTP 请求,就可以获得游戏所需的全部资源。
这篇文章,我们不会从零开始实现我们的目标,除了复用上回的下载器,还会用到 github 上两个好用的开源 JS 库,filer.js 和 zip.js。
filer.js 是对 FileSystem API 的二次封装,提供了更友好的接口和更多的功能; zip.js 提供了解压 Zip 文件的功能。zip.js 源码里的 sjis.js 文件是用来处理日文字符,可以去掉。这两个库的具体使用方法,可以直接去各自的 github 主页查看。
首先,我们还是通过 XHR 下载所需的 Zip 包,指定 responseType 为 arraybuffer。把下载到的数据包装为 Uint8Array,交给 zip.js 解压,这部分代码如下:
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.response != null) {
var result = Zip.inflate(new Uint8Array(this.response));
console.log(result);
}
}
};
xhr.responseType = 'arraybuffer';
xhr.send();
这样,Zip 包就被解压为下面这样格式的数据了:
ZipData 包含很多信息,从命名来看,files 对象中应该只包含文件,但实际上如上图所示,「res/」这样的目录也混在其中,不过我们可以简单地通过最后一个字符来过滤掉它们。每个 file 对象的 data 属性存放的是压缩数据,调用对象的 inflate() 方法会返回这个文件的原始数据。
接下来,我们申请 FileSystem 使用权限,遍历 files 对象,并在 FileSystem 中按照 Zip 包内的目录结构保存文件。这部分代码使用 filer.js 实现很简单,filer.js 提供的 mkdir() 方法可以递归创建多级目录,类似 linux 的「mkdir -p」。另外,FileSystem Api 中操作文件都是异步操作,为了使用方便,我们可以基于 promise 做二次封装。这部分代码不贴了,可以直接看最后的 Demo。
在所有文件都写入完成后,我们获得入口文件(index.html)在 FileSystem 中的地址,直接 location 跳转就可以运行这个游戏了:
filer.create('index.html', false, function(file) {
location.href = file.toURL();
});
完整的 Demo,请点击这里观看。
本文链接:https://mailseason.com/post/a-downloader-with-filesystem-api-2.html,参与评论 »
--EOF--
发表于 2013-10-01 21:12:39,并被添加「FileSystem、HTML5」标签。查看本文 Markdown 版本 »
专题「JavaScript 漫谈」的其他文章 »
- 改进 ThinkJS 的异步编程方式 (May 15, 2015)
- BOM 和 JavaScript 中的 trim (Dec 07, 2013)
- AMD 的 CommonJS wrapping (Dec 05, 2013)
- 用 FileSystem API 实现文件下载器 (Oct 01, 2013)
- ES6 中的 Set、Map 和 WeakMap (Sep 23, 2013)
- ES6 中的生成器函数介绍 (Sep 20, 2013)
- 尝试 ES6 中的箭头函数 (Sep 11, 2013)
- 使用 Canvas 绘制背景图 (Aug 18, 2013)
- 异步编程:When.js快速上手 (Jun 23, 2013)
- JavaScript动画漫谈 (Nov 15, 2012)
Comments
Waline 评论加载中...