Я пишу веб-приложение, которое должно хранить данные JSON в небольшом кеше на стороне сервера фиксированного размера через AJAX (подумайте: Opensocial quotas). Я не контролирую сервер.
Мне нужно уменьшить размер хранимых данных, чтобы оставаться в пределах квоты на стороне сервера, и надеялся, что вы сможете gzip стробированный JSON в браузере, прежде чем отправлять его на сервер.
Однако, я не могу найти много способов реализации JavaScript Gzip. Любые предложения о том, как я могу сжать данные на стороне клиента перед отправкой?
Изменить. Лучшее решение LZW, которое правильно обрабатывает строки Unicode, http://pieroxy.net/blog/pages/lz-string/index.html (спасибо pieroxy в комментариях).
Я не знаю никаких реализаций gzip, но jsolait library (сайт, похоже, ушел) имеет функции сжатия 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, но расшифровывать gzipped данные. Я запускаю javascript-код за пределами браузера, поэтому мне нужно его декодировать с использованием чистого javascript.
Мне понадобилось некоторое время, но я обнаружил, что в библиотеке JSXGraph есть способ чтения gzipped-данных.
Вот где я нашел библиотеку: http://jsxgraph.uni-bayreuth.de/wp/2009/09/29/jsxcompressor-zlib-compressed-javascript-code/ Существует даже автономная утилита, которая может это сделать, JSXCompressor, а код LGPL лицензирован.
Просто включите файл jsxcompressor.js в свой проект, после чего вы сможете прочитать базовые 64-кодированные gzipped-данные:
<!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, и результат двоичный.
var inflate = require('pako/lib/inflate').inflate; var text = inflate(zipped, {to: 'string'});
@Redsandro вот как я использую Пако.
Я поместил реализацию LZMA из модуля GWT в автономный JavaScript. Он назывался LZMA-JS.
Я не тестировал, но там была реализация javascript ZIP, называемая JSZip:
Я предполагаю, что общая реализация сжатия JavaScript на стороне клиента будет очень дорогостоящей операцией с точки зрения времени обработки, в отличие от времени передачи нескольких HTTP-пакетов с несжатой полезной нагрузкой.
Проводите ли вы какое-либо тестирование, которое даст вам представление о том, сколько времени нужно сохранить? Я имею в виду, что экономия полосы пропускания не может быть такой, какой вы хотите, или может?
Большинство браузеров могут распаковывать gzip на лету. Это может быть лучшим вариантом, чем реализация javascript.
Вы можете использовать 1 пиксель на 1 пиксельный Java-апплет, встроенный в страницу, и использовать его для сжатия.
Это не JavaScript, а клиентам потребуется среда выполнения Java, но она будет делать то, что вам нужно.