Реализация 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.

Вот некоторые другие алгоритмы сжатия, реализованные в Javascript:

Я не тестировал, но есть реализация ZIP на JavaScript, называемая JSZip:

http://jszip.stuartk.co.uk/

https://stuk.github.io/jszip/

Я предполагаю, что общая реализация сжатия JavaScript на стороне клиента была бы очень дорогой операцией с точки зрения времени обработки, в отличие от времени передачи еще нескольких пакетов HTTP с несжатой полезной нагрузкой.

Провели ли вы какое-либо тестирование, которое дало бы вам представление о том, сколько времени можно сэкономить? Я имею в виду, экономия полосы пропускания не может быть тем, что вы ищете, или не так ли?

Вы можете использовать встроенный в страницу Java-апплет 1 пиксель на 1 пиксель и использовать его для сжатия.

Это не JavaScript, и клиентам потребуется среда выполнения Java, но она будет делать то, что вам нужно.

Большинство браузеров могут распаковывать gzip на лету. Это может быть лучшим вариантом, чем реализация JavaScript.

Другие вопросы по тегам