การใช้งาน JavaScript ของ Gzip [ปิด]


208

ฉันกำลังเขียนแอปพลิเคชันเว็บที่ต้องการเก็บข้อมูล JSON ในแคชฝั่งเซิร์ฟเวอร์ขนาดเล็กผ่าน AJAX (คิดว่า: โควต้า Opensocial ) ฉันไม่สามารถควบคุมเซิร์ฟเวอร์

ฉันต้องการลดขนาดของข้อมูลที่เก็บไว้เพื่อให้อยู่ในโควต้าฝั่งเซิร์ฟเวอร์และหวังว่าจะสามารถ gzip JSON ที่เป็นสตริงในเบราว์เซอร์ก่อนที่จะส่งไปยังเซิร์ฟเวอร์

อย่างไรก็ตามฉันไม่พบวิธีการใช้งาน JavaScript ของ Gzip มากนัก คำแนะนำใด ๆ สำหรับฉันจะบีบอัดข้อมูลทางฝั่งไคลเอ็นต์ก่อนส่งได้อย่างไร


6
คุณกำลังจะส่งมันขึ้นไปยังเซิร์ฟเวอร์ นั่นเป็นเหตุผลที่มีความคิดของ "อัปโหลด" และ "ดาวน์โหลด" บางทีนั่นอาจเป็นสาเหตุที่คุณได้รับคำตอบที่บอกคุณว่า "เซิร์ฟเวอร์ทำได้"
Tomalak

3
การใช้งานที่เหมาะสมของสิ่งนี้อาจเป็นเรื่องยุ่งยากเนื่องจาก javascript เป็นเธรดเดี่ยว มันอาจจะต้องบีบอัดเป็นชุดโดยใช้ setTimeout () เพื่อที่ UI จะไม่ล็อคขณะบีบอัด
สิงหาคม Lilleaas

บางทีคุณอาจเขียนอัลกอริทึมการบีบอัดของคุณเอง
Captain kurO

3
@AugustLilleaas ตอนนี้คุณสามารถใช้ webworkers เพื่อทำสิ่งนี้ :)
Captain

คำตอบ:


138

แก้ไขดูเหมือนจะเป็นทางออกที่ดีกว่าที่ LZW สตริงจับ Unicode อย่างถูกต้องที่http://pieroxy.net/blog/pages/lz-string/index.html (ขอขอบคุณ pieroxy ในความคิดเห็น)


ฉันไม่รู้การใช้งาน gzip ใด ๆ แต่ห้องสมุด jsolait (เว็บไซต์ดูเหมือนว่าจะหายไป) มีฟังก์ชั่นสำหรับการบีบอัด / คลายการบีบอัด LZW รหัสที่อยู่ภายใต้แอลจี

// 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 \ u0113 ตัวอักษรที่ไม่ใช่ ASCII", 2) ไม่มีรายงานข้อผิดพลาดหากรหัส> 65535
บางส่วน

5
นี่คือการใช้งานใน 21 ภาษาที่แตกต่างกันrosettacode.org/wiki/LZW_compressionมีการเขียนว่ามันเป็นสาธารณสมบัติตั้งแต่ปี 2004
jcubic

5
@some ฉันเพียงแค่ปล่อย lib ขนาดเล็กการแก้ไขว่าปัญหาที่คุณชี้ให้เห็นที่นี่: pieroxy.net/blog/pages/lz-string/index.html
pieroxy

53

ฉันมีปัญหาอื่นผมไม่ต้องการที่จะเข้ารหัสข้อมูลใน gzip แต่เพื่อถอดรหัสข้อมูล gzipped ฉันกำลังเรียกใช้รหัสจาวาสคริปต์นอกเบราว์เซอร์ดังนั้นฉันต้องถอดรหัสโดยใช้จาวาสคริปต์ที่บริสุทธิ์

ฉันใช้เวลาพอสมควร แต่ฉันพบว่าในไลบรารีJSXGraphมีวิธีอ่านข้อมูล gzipped

ที่นี่ฉันพบห้องสมุด: http://jsxgraph.uni-bayreuth.de/wp/2009/09/29/jsxcompressor-zlib-compressed-javascript-code/ มีแม้แต่ยูทิลิตี้แบบสแตนด์อโลนที่สามารถทำได้JSXCompressorและรหัสนั้นเป็นลิขสิทธิ์ของ LGPL

เพียงแค่รวมไฟล์ jsxcompressor.js ในโครงการของคุณจากนั้นคุณจะสามารถอ่านข้อมูล gzipped ที่เข้ารหัส 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>

ฉันเข้าใจว่าไม่ใช่สิ่งที่คุณต้องการ แต่ฉันก็ยังตอบที่นี่เพราะฉันสงสัยว่ามันจะช่วยให้บางคน


3
ขอบคุณมากที่ยังคงแชร์อยู่ นี่คือสิ่งที่ฉันต้องการ คุณอาจช่วยให้ฉันประหยัดเวลาในการค้นหาที่ไม่ประสบความสำเร็จซึ่งฉันไม่สามารถทำได้ +1
Kiruse

1
ฉันสงสัยว่าทำไมบนโลกนี้เรียกว่า "คอมเพรสเซอร์" เมื่อมันเป็นเครื่องบีบอัดข้อมูล 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

เราเพิ่งเปิดตัว pako https://github.com/nodeca/pakoพอร์ตของ zlib ไปยัง javascript ฉันคิดว่านั่นคือการใช้ js ที่เร็วที่สุดของ deflate / inflate / gzip / ungzip นอกจากนี้ยังมีใบอนุญาต 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

ฉันแจ้งการใช้งาน LZMA จากโมดูล GWT เป็น JavaScript แบบสแตนด์อโลน มันเรียกว่าLZMA-JS


1
คุณมีโมดูล php ที่รองรับหรือไม่
Sirber

url นั่นคือ 404 และฉันไม่สามารถหามันได้ในgithub.com/nmruggอย่างใดอย่างหนึ่ง
hanshenrik

ขออภัยลิงค์มีการเปลี่ยนแปลง นี่คือใหม่: lzma-js.github.io/LZMA-JS

14

นี่คืออัลกอริธึมการบีบอัดอื่น ๆ ที่นำมาใช้ใน Javascript:


การใช้งาน LZMA นี้ต้องใช้ BrowserPlus (ส่วนขยายของเบราว์เซอร์) และไม่ได้มองว่าเป็นจาวาสคริปต์ที่แท้จริง
Piotr Findeisen

การใช้งาน LZ77 นี้ไม่สามารถใช้ได้อีกต่อไปและอย่างน้อยก็เป็นรุ่น Python (เผยแพร่ในหน้าเดียวกัน) ไม่ถูกต้องสำหรับอินพุตที่ค่อนข้างง่าย
Piotr Findeisen

geocities dead จะอัปเดตลิงก์
Mauricio Scheffer

มันค่อนข้างใกล้เคียงกับสิ่งที่ฉันต้องการ สิ่งที่ Google ก็จะอัปเดตที่นี่
Theofanis Pantelides


0

ฉันเดาว่าการใช้งานการบีบอัด JavaScript ฝั่งไคลเอ็นต์ทั่วไปจะเป็นการดำเนินการที่แพงมากในแง่ของเวลาในการประมวลผลซึ่งต่างจากเวลาในการถ่ายโอนแพ็กเก็ต HTTP อีกสองสามตัวที่มีการบีบอัดข้อมูลที่ไม่บีบอัด

คุณทำการทดสอบใด ๆ ที่จะให้ความคิดแก่คุณว่ามีเวลามากน้อยเพียงใดในการประหยัด? ฉันหมายถึงการประหยัดแบนด์วิดท์ไม่สามารถเป็นอย่างที่คุณต้องการหรือสามารถทำได้


ฉันจำเป็นต้องรักษาขนาดข้อมูลทั้งหมดไว้ในโควต้าที่กำหนดขนาดนั้นสำคัญกว่าเวลา
David Citron

หืม ... ทำไมถึงมีข้อ จำกัด ? แค่สงสัย.
Tomalak

ทีนี้นี่คือสิ่งที่ Google จะทำ: code.google.com/apis/opensocial/articles/ ...... - โควต้า Opensocial ทั่วไปอยู่ที่ประมาณ 10K
David Citron

ฉันเห็นขอบคุณสำหรับการชี้แจง
Tomalak

1
คุณสามารถใช้เจ้าหน้าที่เว็บเพื่อทำงานเบื้องหลัง
zachleat

-3

เบราว์เซอร์ส่วนใหญ่สามารถขยาย gzip ได้ทันที นั่นอาจเป็นตัวเลือกที่ดีกว่าการใช้ javascript


20
ใช่ แต่ฉันจำเป็นต้องบีบอัดข้อมูลบนฝั่งไคลเอ็นต์ก่อนที่จะส่งลง ...
เดวิด Citron

-4

คุณสามารถใช้แอปเพล็ต Java 1 พิกเซลต่อ 1 พิกเซลที่ฝังอยู่ในหน้าและใช้สำหรับการบีบอัด

ไม่ใช่ JavaScript และลูกค้าจะต้องใช้ Java runtime แต่จะทำสิ่งที่คุณต้องการ


7
น่าสนใจ แต่ฉันควรหลีกเลี่ยงการรวมแอปเพล็ตถ้าเป็นไปได้
David Citron

ฉันต้องการเพิ่มกรณีการใช้งานจริง
cmc

1
ไม่ใช่โซลูชันที่ดีเนื่องจากเพิ่มการพึ่งพา Java นอกเหนือจากนั้นทุกคนไม่ใส่ใจที่จะติดตั้ง java - เว็บไซต์จะไม่ทำงานสำหรับบางคน ส่วนตัวฉันติดตั้งจาวาตั้งแต่ฉันต้องการมันมานานแล้ว แต่ฉันชอบไปที่ไซต์ที่ไม่ได้ใช้จาวา
Onkelborg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.