Внедрение JavaScript в Gzip
Я пишу веб-приложение, которое должно хранить данные JSON в небольшом кеше на стороне сервера фиксированного размера через AJAX (подумайте: Opensocial quotas). Я не контролирую сервер.
Мне нужно уменьшить размер хранимых данных, чтобы оставаться в пределах квоты на стороне сервера, и надеялся, что вы сможете gzip стробированный JSON в браузере, прежде чем отправлять его на сервер.
Однако, я не могу найти много способов реализации JavaScript Gzip. Любые предложения о том, как я могу сжать данные на стороне клиента перед отправкой?
Ответы
Ответ 1
Изменить. Лучшее решение 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("");
}
Ответ 2
У меня была другая проблема, я не хотел кодировать данные в 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>
Я понимаю, что это не то, что вы хотели, но я все еще отвечаю здесь, потому что я подозреваю, что это поможет некоторым людям.
Ответ 3
Мы только что выпустили 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'});
Ответ 4
Я перенес реализацию LZMA из модуля GWT в автономный JavaScript. Это называется LZMA-JS.
Ответ 5
Вот некоторые другие алгоритмы сжатия, реализованные в Javascript:
Ответ 6
Я не тестировал, но там была реализация javascript ZIP, называемая JSZip:
http://jszip.stuartk.co.uk/
https://stuk.github.io/jszip/
Ответ 7
Я предполагаю, что общая реализация сжатия JavaScript на стороне клиента будет очень дорогостоящей операцией с точки зрения времени обработки, в отличие от времени передачи нескольких HTTP-пакетов с несжатой полезной нагрузкой.
Проводите ли вы какое-либо тестирование, которое даст вам представление о том, сколько времени нужно сохранить? Я имею в виду, что экономия полосы пропускания не может быть такой, какой вы хотите, или может?
Ответ 8
Большинство браузеров могут распаковывать gzip на лету. Это может быть лучшим вариантом, чем реализация javascript.
Ответ 9
Вы можете использовать 1 пиксель на 1 пиксельный Java-апплет, встроенный в страницу, и использовать его для сжатия.
Это не JavaScript, а клиентам потребуется среда выполнения Java, но она будет делать то, что вам нужно.