Реализация JavaScript в Gzip
Я пишу веб-приложение, которое должно хранить данные JSON в небольшом серверном кеше фиксированного размера через AJAX (подумайте: квоты Opensocial). У меня нет контроля над сервером.
Мне нужно уменьшить размер хранимых данных, чтобы они не выходили за пределы квоты на стороне сервера, и я надеялся получить возможность сжать зашифрованный JSON в браузере перед его отправкой на сервер.
Однако я не могу найти много способов реализации Gzip на JavaScript. Любые предложения о том, как я могу сжать данные на стороне клиента перед отправкой?
9 ответов
Редактировать Похоже, что есть лучшее решение LZW, которое правильно обрабатывает строки Unicode по адресу http://pieroxy.net/blog/pages/lz-string/index.html (благодаря pieroxy в комментариях).
Я не знаю ни одной реализации gzip, но библиотека jsolait (сайт, кажется, ушел) имеет функции для сжатия / распаковки LZW. Код распространяется под LGPL.
// LZW-compress a string
function lzw_encode(s) {
var dict = {};
var data = (s + "").split("");
var out = [];
var currChar;
var phrase = data[0];
var code = 256;
for (var i=1; i<data.length; i++) {
currChar=data[i];
if (dict[phrase + currChar] != null) {
phrase += currChar;
}
else {
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
dict[phrase + currChar] = code;
code++;
phrase=currChar;
}
}
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
for (var i=0; i<out.length; i++) {
out[i] = String.fromCharCode(out[i]);
}
return out.join("");
}
// Decompress an LZW-encoded string
function lzw_decode(s) {
var dict = {};
var data = (s + "").split("");
var currChar = data[0];
var oldPhrase = currChar;
var out = [currChar];
var code = 256;
var phrase;
for (var i=1; i<data.length; i++) {
var currCode = data[i].charCodeAt(0);
if (currCode < 256) {
phrase = data[i];
}
else {
phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar);
}
out.push(phrase);
currChar = phrase.charAt(0);
dict[code] = oldPhrase + currChar;
code++;
oldPhrase = phrase;
}
return out.join("");
}
У меня была другая проблема, я не хотел кодировать данные в gzip, но декодировать сжатые данные. Я запускаю код JavaScript за пределами браузера, поэтому мне нужно декодировать его с использованием чистого JavaScript.
Это заняло у меня некоторое время, но я обнаружил, что в библиотеке JSXGraph есть способ чтения сжатых данных.
Вот где я нашел библиотеку: http://jsxgraph.uni-bayreuth.de/wp/2009/09/29/jsxcompressor-zlib-compressed-javascript-code/ Существует даже отдельная утилита, которая может сделать это, JSXCompressor и код лицензирован LGPL.
Просто включите файл jsxcompressor.js в свой проект, и тогда вы сможете прочитать данные в сжатом формате, закодированные в формате 64:
<!doctype html>
</head>
<title>Test gzip decompression page</title>
<script src="jsxcompressor.js"></script>
</head>
<body>
<script>
document.write(JXG.decompress('<?php
echo base64_encode(gzencode("Try not. Do, or do not. There is no try."));
?>'));
</script>
</html>
Я понимаю, что это не то, что вы хотели, но я все еще отвечаю здесь, потому что я подозреваю, что это поможет некоторым людям.
Мы только что выпустили pako https://github.com/nodeca/pako, порт zlib для javascript. Я думаю, что сейчас это самая быстрая реализация js для deflate / inflate / gzip / ungzip. Кроме того, он имеет демократическую лицензию MIT. Pako поддерживает все параметры zlib, и его результаты являются бинарными.
Я перенес реализацию LZMA из модуля GWT в автономный JavaScript. Это называется LZMA-JS.
Я не тестировал, но есть реализация ZIP на JavaScript, называемая JSZip:
Я предполагаю, что общая реализация сжатия JavaScript на стороне клиента была бы очень дорогой операцией с точки зрения времени обработки, в отличие от времени передачи еще нескольких пакетов HTTP с несжатой полезной нагрузкой.
Провели ли вы какое-либо тестирование, которое дало бы вам представление о том, сколько времени можно сэкономить? Я имею в виду, экономия полосы пропускания не может быть тем, что вы ищете, или не так ли?
Вы можете использовать встроенный в страницу Java-апплет 1 пиксель на 1 пиксель и использовать его для сжатия.
Это не JavaScript, и клиентам потребуется среда выполнения Java, но она будет делать то, что вам нужно.
Большинство браузеров могут распаковывать gzip на лету. Это может быть лучшим вариантом, чем реализация JavaScript.