最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - using php-gzdeflate and pako-js - Stack Overflow

programmeradmin0浏览0评论

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.

Share asked Jun 20, 2017 at 18:38 edwardsmarkfedwardsmarkf 1,4172 gold badges18 silver badges34 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 3

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 Uint8Arrays, 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>
发布评论

评论列表(0)

  1. 暂无评论