首先,您应该检查 Javascript 中的 gzipping 对于您的目标是否真的必要。如果服务器配置为支持 gzipping 文件,并且浏览器支持 gzipping,则文件(即使是通过 javascript 请求的文件)应自动压缩。
如果您需要采用这种方法(例如,因为您无法控制服务器),那么最好从 Web Worker 中获取文件并在那里进行解压缩。以下代码(使用 gzip 压缩文本文件在 chrome 上测试)假设您在与主脚本和工作程序相同的目录中有 pako_inflate.min.js。另请注意,如果在本地进行测试,您的浏览器可能会出于安全原因阻止从本地文件加载 Web Worker。
只需调用 loadFile 并传递您要加载的文件的名称。完成加载后,将使用数据调用 onFileLoaded。
文件加载器.js
/*
* If you are running this locally your browser may block you from
* loading web worker from a local file. For testing you may want to run
* a simple local web server like so: 'python -m http.server 8000'
*/
var gzippedFileLoaderWorker = new Worker("gzippedFileLoaderWorker.js");
gzippedFileLoaderWorker.onmessage = function (event) {
var message = event.data;
if (message.type == "START") {
console.log(message.data);
} else if (message.type == "END") {
onFileLoaded(message.data);
} else if (message.type == "ERROR") {
console.log(message.data);
}
};
function loadFile(fileName) {
gzippedFileLoaderWorker.postMessage({
type: 'loadFile',
fileName: fileName
});
}
function onFileLoaded(uncompressedFileData) {
console.log("Data Loaded:" + uncompressedFileData);
}
gzippedFileLoaderWorker.js
importScripts('pako_inflate.min.js');
onmessage = function(event) {
var message = event.data;
if (message.type === "loadFile") {
postMessage({
'type' : 'START',
'data' : "Started Downloading: " + message.fileName
});
try {
/*
* Fetch is not supported on ie yet. If this is a requirement
* find a polyfill like whatwg-fetch
*/
fetch(message.fileName).then(function(response) {
if (!response["ok"]) {
postMessage({
'type' : 'ERROR',
'data' : "Error loading: " + message.fileName
})
}
return response["arrayBuffer"]();
}).then(function(zipped) {
return pako.ungzip(new Uint8Array(zipped));
}).then(function(binary) {
/*
* Do any processing on the binary data here so you don't
* block the main thread! Then pass that data back as an
* object instead of the binary in the post message
*/
postMessage({
'type' : 'END',
'data' : binary
});
});
} catch(err) {
postMessage({
'type' : 'ERROR',
'data' : err.message
});
}
}
}