web-dev-qa-db-fra.com

Implémentation JavaScript de Gzip

J'écris une application Web qui doit stocker les données JSON dans un petit cache côté serveur de taille fixe via AJAX (pensez: quotas Opensocial ). Je n'ai pas de contrôle sur le serveur.

Je devais réduire la taille des données stockées pour rester dans les limites d'un quota côté serveur. J'espérais pouvoir gzip le fichier JSON codifié dans le navigateur avant de l'envoyer au serveur.

Cependant, je ne trouve pas grand-chose dans la voie des implémentations JavaScript de Gzip. Avez-vous des suggestions pour compresser les données côté client avant de les envoyer?

202
David Citron

Edit Il semble qu'il existe une meilleure solution LZW qui gère correctement les chaînes Unicode à l'adresse http://pieroxy.net/blog/pages/lz -string/index.html (Merci à pieroxy dans les commentaires).


Je ne connais aucune implémentation de gzip, mais la bibliothèque jsolait (le site semble avoir disparu) possède des fonctions de compression/décompression LZW. Le code est couvert par 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("");
}
132
Matthew Crumley

J'ai eu un autre problème, je ne voulais pas encoder les données dans gzip mais décoder les données gzippées . J'utilise du code javascript en dehors du navigateur, je dois donc le décoder à l'aide de pur javascript.

Cela m'a pris du temps mais j'ai trouvé que dans la bibliothèque JSXGraph , il existe un moyen de lire les données gzippées.

Voici où j'ai trouvé la bibliothèque: http://jsxgraph.uni-bayreuth.de/wp/2009/09/29/jsxcompressor-zlib-compressed-javascript-code/ Il y a même une version autonome Utilitaire qui peut faire cela, JSXCompressor , et le code est autorisé par LGPL.

Incluez simplement le fichier jsxcompressor.js dans votre projet et vous pourrez alors lire des données gzippées codées en base 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>

Je comprends que ce n’est pas ce que vous vouliez, mais je réponds quand même parce que je soupçonne que cela aidera certaines personnes.

50
pcans

Nous venons de publier pako https://github.com/nodeca/pako , port de zlib vers javascript. Je pense que c’est maintenant l’implémentation js la plus rapide de deflate/inflate/gzip/ungzip. En outre, il possède une licence MIT démocratique. Pako supporte toutes les options zlib et ses résultats sont égaux en binaire.

Exemple:

var inflate = require('pako/lib/inflate').inflate; 
var text = inflate(zipped, {to: 'string'});
36
Vitaly

J'ai porté une implémentation de LZMA d'un module GWT en JavaScript autonome. Cela s'appelle LZMA-JS .

17
nmrugg

Voici quelques autres algorithmes de compression implémentés en Javascript:

14
Mauricio Scheffer

Je n'ai pas testé, mais il existe une implémentation javascript de Zip, appelée JSZip:

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

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

8
Sirber

Je suppose qu'une implémentation générique de la compression JavaScript côté client serait une opération très coûteuse en temps de traitement par opposition au temps de transfert de quelques paquets HTTP supplémentaires avec une charge utile non compressée.

Avez-vous effectué des tests qui vous donneraient une idée du temps qu'il vous reste à économiser? Je veux dire, les économies de bande passante ne peuvent pas être ce que vous cherchez, ou peut-il?

0
Tomalak