diff --git a/examples/browser.html b/examples/browser.html index 983ff5c..0b6ab7e 100644 --- a/examples/browser.html +++ b/examples/browser.html @@ -39,25 +39,41 @@ var data = unescape(encodeURIComponent(str)); // For ancient ones - more work needed. // -var result = pako.deflate(data); +var resultAsUint8Array = pako.deflate(data); +var resultAsBinString = pako.deflate(data, { to: 'string' }); // Send data to server ///////////////////////////////////////////////////////// -function send() { +function sendModern() { var xhr = new XMLHttpRequest; - console.log('Sending data...'); + console.log('Sending data in modern browsers...'); xhr.open('POST', 'http://localhost:8000/', true); - // Modern browsers support sending typed array directly - xhr.send(result); + // We could make this work everywhere, if send data as base64 string. + // But that will add 25% of size. + xhr.send(resultAsUint8Array); - setTimeout(send, 2000); + setTimeout(sendModern, 2000); } -send(); +function sendAncient() { + var xhr = new XMLHttpRequest; + + console.log('Sending data in ancient browsers...'); + + xhr.open('POST', 'http://localhost:8000/', true); + // Kludge to send binary strings as is. + xhr.overrideMimeType('text/plain; charset=x-user-defined'); + xhr.send(resultAsBinString); + + setTimeout(sendAncient, 2000); +} + +sendModern(); +sendAncient(); diff --git a/examples/server.js b/examples/server.js index 233d99a..781ee64 100644 --- a/examples/server.js +++ b/examples/server.js @@ -5,20 +5,6 @@ const http = require('http'); const pako = require('../'); -//////////////////////////////////////////////////////////////////////////////// -// This is the main part of example - -function processData(bin) { - // Decompress binary content or POST request - let uncompressed = pako.inflate(new Uint8Array(bin), { to: 'string' }); - - // Convert utf8 -> utf16 - let decoded = decodeURIComponent(escape(uncompressed)); - - console.log(decoded); -} - -//////////////////////////////////////////////////////////////////////////////// const server = http.createServer((req, res) => { var buf = []; @@ -26,10 +12,47 @@ const server = http.createServer((req, res) => { req.on('data', data => buf.push(data)); req.on('end', () => { + console.log('--- received request'); + + // In ideal world, we should process data as stream to minimize memory use + // on big data (and use node's `zlib` inflate). + // + // But that's just a quick sample to explain data reencoding steps from + // browser to server. Feel free to improve. + + // Join all pending chunks. let bin = Buffer.concat(buf); - processData(bin); + // Test header to understand if data was sent as raw binary (modern browser) + // or string (utf8) format. If utf8 - reencode to binary. + // + // We could also use base64 encoding for strings on client side, but that + // needs more libraries for old browsers (for unsupported `window.btoa()`). + // + // If you don't need IE8/9 support - just drop this part. + if (req.headers['content-type'] && + /text\/plain/i.test(req.headers['content-type']) && + /UTF-8/i.test(req.headers['content-type'])) { + console.log('--- data has utf-8 encoding'); + bin = Buffer.from(bin.toString(), 'binary'); + } + + // Decompress binary content + // Note! Can throw error on bad data + let uncompressed = pako.inflate(new Uint8Array(bin), { to: 'string' }); + + // Convert utf8 -> utf16 (native JavaScript string format) + let decoded = decodeURIComponent(escape(uncompressed)); + + // Finally, create an object + // Note! Can throw error on bad data + let obj = JSON.parse(decoded); + + console.log('--- received object is: ', obj); + + // Quick hack to bypass security restrictions when demo html is opened from + // file system. Don't do such things on production. res.setHeader('Access-Control-Allow-Origin', '*'); res.end('ok'); });