Gzip'in JavaScript uygulaması [kapalı]


208

AJON ile küçük, sabit boyutlu bir sunucu tarafı önbelleğinde JSON verilerini depolaması gereken bir Web uygulaması yazıyorum (düşünün: opensocial kotaları ). Sunucu üzerinde kontrolüm yok.

Bir sunucu tarafı kota içinde kalmak için depolanan verilerin boyutunu azaltmak gerekiyor ve sunucuya göndermeden önce tarayıcıda dizeli JSON gzip edebilmek umuyordum.

Ancak, Gzip'in JavaScript uygulamalarında pek bir şey bulamıyorum. Göndermeden önce istemci tarafındaki verileri nasıl sıkıştırabileceğim konusunda herhangi bir öneriniz var mı?


6
Bunu gönderiyor kadar sunucuya. Bu yüzden "yükle" ve "indir" kavramları vardır. Belki de bu yüzden size "sunucu bunu yapabilir" diyen cevaplar alıyorsunuz.
08:27

3
Javascript tek iş parçacıklı olduğundan, bunun doğru bir şekilde uygulanması muhtemelen zor. Muhtemelen setTimeout () kullanarak toplu olarak sıkıştırması gerekir, böylece sıkıştırma sırasında UI kilitlenmez.
Ağustos Lilleaas

belki kendi sıkıştırma algoritmanızı yazabilirsiniz
Kaptan kurO

3
@AugustLilleaas şimdi bunu yapmak için webworkers kullanabilirsiniz :)
Kaptan Obvious

Yanıtlar:


138

Düzenle http://pieroxy.net/blog/pages/lz-string/index.html adresinde Unicode dizelerini doğru işleyen daha iyi bir LZW çözümü var gibi görünüyor (yorumlardaki pieroxy sayesinde).


Herhangi bir gzip uygulaması bilmiyorum, ama jsolait kütüphanesi (site gitmiş gibi görünüyor) LZW sıkıştırma / açma için fonksiyonları vardır. Kod LGPL kapsamındadır .

// 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("");
}

11
Wikipedia'ya göre patentlerin süresi birkaç yıl önce dolmuştu. Yine de bunu kontrol etmek iyi bir fikir olabilir.
Matthew Crumley

3
LZW hala patentlenemeyecek kadar eski. Son patentler 2003 yılında tükendi. Bir sürü ücretsiz uygulama var.
ypnos

5
Yukarıdaki kodla ilgili en az iki sorun görüyorum: 1) "Bunu sıkıştırmak için test et \ u0110 \ u0111 \ u0112 \ u0113 \ u0114 ascii olmayan karakterler.", 2) Kod> 65535 ise hata bildirilmedi.
bazı

5
İşte 21 farklı dilde uygulamalar rosettacode.org/wiki/LZW_compression 2004 yılından
beri

5
@some burada tam olarak işaret ettiğiniz sorunları düzelten küçük bir lib yayınladım: pieroxy.net/blog/pages/lz-string/index.html
pieroxy

53

Başka bir sorun vardı, gzip veri kodlamak istemiyordu ama gzipped veri kodunu çözmek için . Ben saf javascript kullanarak kodunu çözmek için tarayıcı dışında javascript kodu çalıştırıyorum .

Biraz zaman aldı ama JSXGraph kütüphanesinde gzip veri okumak için bir yol olduğunu buldum .

Kütüphaneyi bulduğum yer: http://jsxgraph.uni-bayreuth.de/wp/2009/09/29/jsxcompressor-zlib-compressed-javascript-code/ Bunu yapabilen bağımsız bir yardımcı program bile var, JSXCompressor ve kod LGPL lisanslıdır.

Sadece projenize jsxcompressor.js dosyasını dahil edin ve daha sonra temel 64 kodlu gziplenmiş verileri okuyabileceksiniz:

<!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>

İstediğiniz şey olmadığını anlıyorum ama yine de burada cevap veriyorum çünkü bazı insanlara yardımcı olacağından şüpheleniyorum.


3
Hala paylaştığınız için çok teşekkür ederim. Tam da ihtiyacım olan şey bu. Muhtemelen bana gerçekten ayıramayacağım saatlerce başarısız arama kurtardın. +1
Kiruse

1
Bir UNcompressor olduğunda neden "kompresör" olarak adlandırıldığını merak ediyorum. lol
matteo

1
neredeyse 5 yıl sonra hala faydalı. teşekkür ederim. AJAX'ing yerine büyük bir JSON'u doğrudan sayfaya döküyorum. PHP ile önceden sıkıştırarak ve JavaScript'in istemci tarafında geri açarak - bazı ek yükü kaydediyorum.

<?php..Biraz ihtiyacımız var mı? .. Soruyorum çünkü decompressyönteme geçti .
Jus12

i olsun14:16:28.512 TypeError: e.replace is not a function[Weitere Informationen] jsxcompressor.min.js:19:12201
Bluscream

40

Zlib'in javascript limanı pako https://github.com/nodeca/pako yayınladık . Ben şimdi bu deflate / inflate / gzip / ungzip'in en hızlı js uygulaması olduğunu düşünüyorum. Ayrıca, demokratik MIT lisansına sahiptir. Pako tüm zlib seçeneklerini destekler ve sonuçları ikili olarak eşittir.

Misal:

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

7
Lütfen sıkıştırılmış dizelerin kodunu çözmek için istemci tarafı bir örnek verin.
Mart'ta Redsandro

2
var inflate = require('pako/lib/inflate').inflate; var text = inflate(zipped, {to: 'string'});@Redandro şu şekilde pako kullanıyorum.
forresto

Bu müşteri örneği atarincorrect header check
duhaime


14

Javascript'te uygulanan diğer sıkıştırma algoritmaları şunlardır:


Bu LZMA uygulaması BrowserPlus (bir tarayıcı uzantısı) gerektirir ve saf görünmüyor Javascript
Piotr Findeisen

bu LZ77 uygulaması artık mevcut değildir ve en azından Python sürümü (aynı sayfada yayınlanan) oldukça basit girdiler için yanlıştır.
Piotr Findeisen

geocities öldü, bağlantı güncelleyecek
Mauricio Scheffer

Bu istediğime oldukça yakın. googling şeyler de burada güncellenecek
Theofanis Pantelides


0

Genel bir istemci tarafı JavaScript sıkıştırma uygulaması, sıkıştırılmamış yararlı yüke sahip birkaç HTTP paketinin aktarım süresinin aksine işlem süresi açısından çok pahalı bir işlem olacaktır.

Size ne kadar zaman kazandıracağınıza dair bir fikir verecek herhangi bir test yaptınız mı? Yani, bant genişliği tasarrufu peşinde olduğunuz şey olamaz ya da değil mi?


Toplam veri boyutunu belirli bir kota içinde tutmam gerekiyor - boyut zamandan daha önemli.
David Citron

Hm ... Sınır neden? Sadece merak.
Tomalak

İşte Google bunu ele alıyor: code.google.com/apis/opensocial/articles/… - Tipik opensocial kotaları yaklaşık 10 bin.
David Citron

Anladım, açıklama için teşekkürler.
Tomalak

1
Sıkıştırmanın ne kadar yoğun olduğuna bağlı olarak, işi sahne arkasında gerçekleştirmek için web çalışanlarını kullanabilirsiniz.
zachleat

-3

Çoğu tarayıcı anında gzip sıkıştırmasını açabilir. Bu bir JavaScript uygulamasından daha iyi bir seçenek olabilir.


20
Evet, ama göndermeden önce istemci tarafındaki verileri sıkıştırmam gerekiyor ...
David Citron

-4

Sayfaya gömülü 1 piksel Java uygulaması başına 1 piksel kullanabilir ve bunu sıkıştırma için kullanabilirsiniz.

JavaScript değil ve istemcilerin bir Java çalışma zamanına ihtiyacı olacak, ancak ihtiyacınız olanı yapacak.


7
İlginç, ancak mümkünse bir applet eklemeyi tercih ederim.
David Citron

Gerçek kullanım durumlarını eklemek istiyorum
cmc

1
Java'ya bağımlılık kattığı için iyi bir çözüm değil. Bunun dışında, herkes java yüklemek için uğraşmadı - site bazı insanlar için çalışmaz. Şahsen, uzun zaman önce bir şeye ihtiyacım olduğu için java yükledim, ancak java kullanmayan siteleri ziyaret etmeyi tercih ediyorum.
Onkelborg
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.