Gzip의 자바 스크립트 구현


208

AJAX를 통해 JSON 데이터를 작은 고정 크기 서버 측 캐시에 저장 해야하는 웹 응용 프로그램을 작성 중입니다 (생각 : Opensocial quotas ). 서버를 제어 할 수 없습니다.

서버 측 할당량 내에 유지하기 위해 저장된 데이터의 크기를 줄여야하며 서버로 전송하기 전에 브라우저에서 문자열 화 된 JSON을 압축 할 수 있기를 바랐습니다.

그러나 Gzip의 JavaScript 구현 방식을 많이 찾을 수는 없습니다. 클라이언트 측에서 데이터를 전송하기 전에 압축하는 방법에 대한 제안 사항이 있습니까?


6
당신은 그것을 보낼 까지 서버에. 이것이 "업로드"와 "다운로드"라는 개념이있는 이유입니다. 어쩌면 "서버가 할 수 있습니다"라는 응답이 표시 될 수 있습니다.
Tomalak

3
자바 스크립트는 단일 스레드이기 때문에 적절한 구현은 까다로울 수 있습니다. 압축하는 동안 UI가 잠기지 않도록 setTimeout ()을 사용하여 일괄 압축해야 할 수도 있습니다.
August Lilleaas

아마도 당신은 당신 자신의 압축 알고리즘을 작성할 수 있습니다
kurO CAPO

3
@AugustLilleaas 이제 웹 워크를 사용하여이 작업을 수행 할 수 있습니다 :)
Captain Obvious

답변:


138

편집 http://pieroxy.net/blog/pages/lz-string/index.html (의견에 pieroxy 감사 합니다)에는 유니 코드 문자열을 올바르게 처리하는 더 나은 LZW 솔루션이 있는 것으로 보입니다.


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

11
Wikipedia에 따르면 특허는 몇 년 전에 만료되었습니다. 그래도 확인하는 것이 좋습니다.
Matthew Crumley

3
LZW는 아직 특허를 받기에는 너무 오래되었습니다. 마지막 특허는 2003 년 정도에 만료되었습니다. 많은 무료 구현이 있습니다.
ypnos

5
위 코드에서 적어도 두 가지 문제가 있습니다. 1) "이 \ u0110 \ u0111 \ u0112 \ u0113 \ u0114 비 ASCII 문자를 압축하는 테스트"를 압축하십시오., 2) 코드가 65535보다 크면 오류가보고되지 않습니다.
일부

5
여기 구현은 21 개 개의 다른 언어에있는이 rosettacode.org/wiki/LZW_compression 가가 2004에서 공개 도메인에 있다고 쓰여
jcubic

5
@ some 나는 방금 당신이 지적하고있는 문제를 정확하게 수정하는 작은 라이브러리를 발표했습니다 : pieroxy.net/blog/pages/lz-string/index.html
pieroxy

53

다른 문제가 있었는데 gzip으로 데이터를 인코딩하고 싶지 않고 gzip으로 압축 된 데이터디코딩 하고 싶습니다 . 브라우저 외부에서 자바 스크립트 코드를 실행 중이므로 순수한 자바 스크립트를 사용하여 디코딩해야합니다 .

시간이 좀 걸렸지 만 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
여전히 공유해 주셔서 감사합니다. 이것이 바로 내가 필요한 것입니다. 당신은 아마 내가 정말로 여유가없는 검색에 실패한 시간을 절약했습니다. +1
Kiruse

1
UNcompressor 일 때 왜 "compressor"라고 불리는 지 궁금합니다. lol
matteo

1
거의 5 년 후에도 여전히 유용합니다. 감사합니다. 큰 JSON을 AJAX 대신 페이지에 직접 덤프하고 있습니다. PHP로 미리 압축하고 JavaScript의 클라이언트 측에서 다시 압축 해제하여 오버 헤드를 절약합니다.

<?php..비트 가 필요 합니까? .. decompress메소드에 전달되기 때문에 묻습니다 .
Jus12

나는 얻는다14:16:28.512 TypeError: e.replace is not a function[Weitere Informationen] jsxcompressor.min.js:19:12201
Bluscream

40

방금 palib https://github.com/nodeca/pako , zlib 포트를 javascript로 릴리스했습니다 . 나는 그것이 deflate / inflate / gzip / ungzip의 가장 빠른 js 구현이라고 생각합니다. 또한 민주적 MIT 라이센스가 있습니다. Pako는 모든 zlib 옵션을 지원하며 결과는 이진 동일합니다.

예:

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

7
gzipped 문자열을 디코딩하기위한 클라이언트 측 예제를 제공하십시오.
Redsandro

2
var inflate = require('pako/lib/inflate').inflate; var text = inflate(zipped, {to: 'string'});@Redsandro 여기에 pako를 사용하는 방법이 있습니다.
forresto

즉, 클라이언트 측의 예를 던졌습니다incorrect header check
duhaime

17

GWT 모듈에서 LZMA 구현을 독립형 JavaScript로 이식했습니다. LZMA-JS 라고 합니다.


1
호환되는 PHP 모듈이 있습니까?
Sirber

URL이 404이고, 나는 그것을 찾을 수 없습니다 github.com/nmrugg
hanshenrik

죄송합니다. 링크가 변경되었습니다. 여기에 새입니다 lzma-js.github.io/LZMA-JS

14

다음은 자바 스크립트로 구현 된 다른 압축 알고리즘입니다.


이 LZMA 구현은 BrowserPlus (브라우저 확장)가 필요합니다 자바 스크립트 순수한 것으로 보이지 않는다
표트르 FINDEISEN

이 LZ77 구현은 더 이상 사용할 수 없으며 적어도 동일한 페이지에 게시 된 Python 버전은 매우 간단한 입력에 대해 올바르지 않습니다.
Piotr Findeisen

geocities 사망, 링크를 업데이트합니다
Mauricio Scheffer

이것은 내가 원하는 것에 아주 가깝습니다. 인터넷 검색도 여기에 업데이트됩니다
Theofanis Pantelides


0

압축되지 않은 페이로드가있는 몇 가지 HTTP 패킷의 전송 시간과는 달리 처리 시간 측면에서 일반적인 클라이언트 측 JavaScript 압축 구현은 비용이 많이 드는 작업이라고 생각합니다.

얼마나 많은 시간을 절약해야하는지 알 수있는 테스트를 수행 했습니까? 내 말은, 대역폭 절약은 당신이 추구하는 것이 될 수 없습니까?


특정 할당량 내에서 총 데이터 크기를 유지해야합니다. 크기는 시간보다 중요합니다.
David Citron

흠 ... 왜 한계가 있습니까? 그냥 궁금해서
Tomalak

자, 여기에 구글이 있습니다 : code.google.com/apis/opensocial/articles/…- 일반적인 오픈 소셜 할당량은 약 10K입니다.
David Citron

설명해 주셔서 감사합니다.
Tomalak

1
압축 강도에 따라 웹 워커를 사용하여 배후에서 작업을 수행 할 수 있습니다.
zachleat

-3

대부분의 브라우저는 gzip을 즉시 압축 해제 할 수 있습니다. 그것은 자바 스크립트 구현보다 더 나은 옵션 일 수 있습니다.


20
네,하지만 ... 그것을 내려 보내기 전에 클라이언트 측에서 데이터를 압축 할 필요가
데이비드 유자

-4

페이지에 임베드 된 1 픽셀 Java 애플릿 당 1 픽셀을 사용하여 압축에 사용할 수 있습니다.

JavaScript가 아니며 클라이언트는 Java 런타임이 필요하지만 필요한 작업을 수행합니다.


7
흥미롭지 만 가능하면 애플릿을 포함하지 않는 것이 좋습니다.
David Citron

실제 사용 사례를 추가하고 싶습니다
cmc

1
Java에 대한 종속성을 추가하므로 좋은 솔루션이 아닙니다. 그 외에도 모든 사람이 자바를 설치하는 것을 귀찮게하지는 않았습니다.이 사이트는 일부 사람들에게는 작동하지 않습니다. 개인적으로 나는 오래 전에 무언가를 필요로했기 때문에 Java를 설치했지만 Java를 사용하지 않는 사이트를 방문하는 것을 선호합니다.
Onkelborg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.