i am attempting to bine php-gzdeflate and pako. to press the string i am using:
const pressed = ' <?php echo base64_encode(gzdeflate('Compress me')); ?> ' ;
// pressed now contains: c87PLShKLS5WyE0FAA==
but i cannot seem to read this string back using pako. i have tried the following:
var enc = new TextEncoder("utf-8");
pako.ungzip(enc.encode(pressed) );
i get this message back: uncaught incorrect header check
is there a simple way to press using generic-php and inflate using pako?
so far i have tried adding various gzdeflate "levels" from one to nine, but none of them appear to make any difference. and at this point, i am just guessing.
and we would rather not install any special extension to php if possible
thank you very much.
i am attempting to bine php-gzdeflate and pako. to press the string i am using:
const pressed = ' <?php echo base64_encode(gzdeflate('Compress me')); ?> ' ;
// pressed now contains: c87PLShKLS5WyE0FAA==
but i cannot seem to read this string back using pako. i have tried the following:
var enc = new TextEncoder("utf-8");
pako.ungzip(enc.encode(pressed) );
i get this message back: uncaught incorrect header check
is there a simple way to press using generic-php and inflate using pako?
so far i have tried adding various gzdeflate "levels" from one to nine, but none of them appear to make any difference. and at this point, i am just guessing.
and we would rather not install any special extension to php if possible
thank you very much.
Update to @edwardsmarkf's answer you can solve this without the atos function now. Most newer browsers have the TextDecoder api. You can use it like so:
const decoder = new TextDecoder();
const result = decoder.decode(pako.ungzip(atob(pressedBase64Data)));
I couldn't get the answers here to work, so I did some research.
As PleaseStand
pointed out here, the problem is that PHP uses UTF-8 strings, while JS uses UTF-16 strings. Hence, the binary string to base64 string encoding will differ.
The solution I used is to force JS to interpret the data as UTF-8. This is straightforward, as pako
accepts and returns Uint8Array
s, which are essentially UTF-8 strings.:
Compress in JS, Depress in PHP:
//JS
const pako = require('pako');
const press = str => Buffer.from(pako.deflateRaw(str)).toString('base64');
console.log(press('asdfasdfasdfasdf')); //SyxOSUtEwgA=
//PHP
function depress($str) { return gzinflate(base64_decode($str)); }
echo depress('SyxOSUtEwgA='); //asdfasdfasdfasdf
Compress in PHP, Depress in JS:
//PHP
function press($str) { return base64_encode(gzdeflate($str, 9)); }
echo press('asdfasdfasdf'); //SyxOSUuEYgA=
//JS
const pako = require('pako');
const depress = str => pako.inflateRaw(Buffer.from(str, 'base64'), {to: 'string'});
console.log(depress('SyxOSUuEYgA=')); //asdfasdfasdfs
Note: Buffer
instances are also Uint8Array
instances, hence we don't need to convert the Buffer
to a Uint8Array
before giving it to pako.
These functions are also patible within the languages:
//JS
console.log(depress(press('asdfasdfasdfasdf'))); //asdfasdfasdfasdf
//PHP
echo depress(press('asdfasdfasdfasdf')); //asdfasdfasdfasdf
For JS, this works out of the box in NodeJs. In a browser environment, you will need a polyfil for Buffer
.
For PHP, remember to install the Zlib
extension.
I'm not familiar with php, so I kinda struggled with this problem, so I thought to post a minimal working solution in php:
$response = gzdeflate('My data', 9, ZLIB_ENCODING_DEFLATE);
header('Content-Encoding: deflate');
echo $response;
No need to use pako after this, the data will be depressed by the browser.
Example if you're requesting json formatted data:
$.ajax({
type: 'GET',
url: 'http://target.',
dataType: "json",
contentType: "application/json; charset=utf-8",
headers : {'Accept-Encoding': 'deflate '},
})
.done(function(res) {
console.log(res)
})
.fail(function(xhr, textStatus, errorThrown) {
});
This appears to work(below)
Steps involved:
server side (php):
1) gzdeflate using ZLIB_ENCODING_DEFLATE option
2) base64_encode
client side:(jScript)
1) atob
2) pako.ungzip
3) atos function
<script src='//cdnjs.cloudflare./ajax/libs/pako/1.0.5/pako_deflate.js' type='text/javascript'></script>
<script type='text/javascript'>
const pressedDEFLATE = '<?php echo base64_encode(gzdeflate('Compress me', 6, ZLIB_ENCODING_DEFLATE )); ?>' ;
function atos(arr) {
for (var i=0, l=arr.length, s='', c; c = arr[i++];)
s += String.fromCharCode(
c > 0xdf && c < 0xf0 && i < l-1
? (c & 0xf) << 12 | (arr[i++] & 0x3f) << 6 | arr[i++] & 0x3f
: c > 0x7f && i < l
? (c & 0x1f) << 6 | arr[i++] & 0x3f
: c
);
return s
}
alert ( atos(pako.ungzip( atob(pressedDEFLATE) ) ) );
</script>