215 votes

Implémentation JavaScript de Gzip

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

Je dois réduire la taille des données stockées pour respecter un quota côté serveur, et j'espérais pouvoir compresser le JSON dans le navigateur avant de l'envoyer au serveur.

Cependant, je ne trouve pas beaucoup d'implémentations JavaScript de Gzip. Avez-vous des suggestions sur la façon dont je peux compresser les données côté client avant de les envoyer ?

7 votes

Vous l'envoyez en haut au serveur. C'est pour cela qu'il existe les notions d'"upload" et de "download". C'est peut-être pour cela que vous obtenez des réponses qui vous disent "le serveur peut le faire".

3 votes

Une mise en œuvre correcte de ce système est probablement délicate, puisque le javascript est monofilaire. Il faudrait probablement compresser par lots, en utilisant setTimeout(), afin que l'interface utilisateur ne se bloque pas pendant la compression.

0 votes

Vous pourriez peut-être écrire votre propre algorithme de compression

149voto

Matthew Crumley Points 47284

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


Je ne connais pas d'implémentation de gzip, mais la fonction bibliothèque jsolait (le site semble avoir disparu) a des fonctions pour la compression/décompression LZW. Le code est couvert par la 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 votes

Comment le code peut-il être LGPL si l'algorithme est breveté ? Ou bien tous les brevets sont-ils vraiment expirés ?

11 votes

Selon Wikipedia, les brevets ont expiré il y a quelques années. Ce serait une bonne idée de le vérifier.

3 votes

LZW est bien trop vieux pour être encore breveté. Les derniers brevets ont expiré en 2003 environ. Il existe de nombreuses implémentations libres.

60voto

pcans Points 3554

J'avais un autre problème, je ne voulais pas encoder les données en gzip mais en décoder les données gzippées . J'exécute du code javascript en dehors du navigateur et j'ai donc besoin de le décoder à l'aide de pur javascript.

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

C'est ici que j'ai trouvé la bibliothèque : http://jsxgraph.uni-bayreuth.de/wp/2009/09/29/jsxcompressor-zlib-compressed-javascript-code/ Il existe même un utilitaire autonome qui peut le faire, JSXCompressor et le code est sous licence LGPL.

Il suffit d'inclure le fichier jsxcompressor.js dans votre projet pour pouvoir 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 ici parce que je pense que cela peut aider certaines personnes.

3 votes

Merci beaucoup de continuer à partager. C'est exactement ce dont j'avais besoin. Vous m'avez probablement épargné des heures de recherches infructueuses dont je ne peux vraiment pas me passer. +1

1 votes

Je me demande pourquoi diable on l'appelle "compresseur" alors que c'est un décompresseur. lol

1 votes

Presque 5 ans plus tard, toujours utile. merci. Je déverse un gros JSON directement sur la page, au lieu de l'AJAX'ing. En le pré-compressant avec PHP et en le décompressant de nouveau dans JavaScript côté client - je sauve une partie de l'overhead.

43voto

Vitaly Points 190

Nous venons de publier pako https://github.com/nodeca/pako portage de zlib en javascript. Je pense que c'est maintenant l'implémentation js la plus rapide de deflate / inflate / gzip / ungzip. De plus, il a une licence MIT démocratique. Pako supporte toutes les options de zlib et ses résultats sont binaires.

Ejemplo:

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

7 votes

Veuillez fournir un exemple côté client pour le décodage des chaînes gzippées.

2 votes

var inflate = require('pako/lib/inflate').inflate; var text = inflate(zipped, {to: 'string'}); @Redsandro voici comment j'utilise pako.

0 votes

Cet exemple côté client jette incorrect header check

17voto

nmrugg Points 311

J'ai porté une mise en œuvre de LZMA à partir d'un module GWT en JavaScript autonome. Il s'appelle LZMA-JS .

1 votes

Avez-vous un module php compatible ?

14voto

Mauricio Scheffer Points 70470

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

0 votes

Cette implémentation de LZMA nécessite BrowserPlus (une extension de navigateur) et ne semble pas être du pur Javascript.

0 votes

Cette implémentation de LZ77 n'est plus disponible et au moins sa version Python (publiée sur la même page) était incorrecte pour des entrées assez simples.

0 votes

Geocities est mort, je vais mettre à jour le lien

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X