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.