使用php-gzdeflate和pako-js

时间:2017-06-20 18:38:00

标签: javascript php pako

我正在尝试合并php-gzdeflatepako。压缩我正在使用的字符串:

const compressed = ' <?php echo base64_encode(gzdeflate('Compress me')); ?> ' ;
// compressed now contains: c87PLShKLS5WyE0FAA==

但我似乎无法使用pako读回这个字符串。我尝试了以下内容:

var enc = new TextEncoder("utf-8");
pako.ungzip(enc.encode(compressed) );

我收到此消息:未捕获错误的标题检查

是否有一种简单的方法可以使用generic-php进行压缩并使用pako进行充气?

到目前为止,我已尝试添加各种gzdeflate&#34;等级&#34;从一到九,但它们似乎没有任何区别。而在这一点上,我只是在猜测。

如果可能的话,我们宁愿不安装任何特殊的扩展名

非常感谢你。

3 个答案:

答案 0 :(得分:2)

更新为@edwardsmarkf的答案,您现在就可以解决这个问题,而无需使用atos函数。大多数较新的浏览器都具有TextDecoder API。您可以像这样使用它:

const decoder = new TextDecoder();
const result = decoder.decode(pako.ungzip(atob(compressedBase64Data)));

答案 1 :(得分:1)

我在这里找不到答案,所以我做了一些研究。

正如PleaseStand指出的here一样,问题是PHP使用UTF-8字符串,而JS使用UTF-16字符串。因此,二进制字符串到base64字符串的编码将有所不同。

我使用的解决方案是强制JS将数据解释为UTF-8。这很简单,因为pako接受并返回Uint8Array,它们本质上是UTF-8字符串。:

在JS中压缩,在PHP中解压缩:

//JS
const pako = require('pako');
const compress = str => Buffer.from(pako.deflateRaw(str)).toString('base64');
console.log(compress('asdfasdfasdfasdf')); //SyxOSUtEwgA=
//PHP
function decompress($str) { return gzinflate(base64_decode($str)); }
echo decompress('SyxOSUtEwgA='); //asdfasdfasdfasdf

在PHP中压缩,在JS中解压缩:

//PHP
function compress($str) { return base64_encode(gzdeflate($str, 9)); }
echo compress('asdfasdfasdf'); //SyxOSUuEYgA=
//JS
const pako = require('pako');
const decompress = str => pako.inflateRaw(Buffer.from(str, 'base64'), {to: 'string'});
console.log(decompress('SyxOSUuEYgA=')); //asdfasdfasdfs

注意:Buffer instances are also Uint8Array instances,因此在将其交给pako之前,无需将Buffer转换为Uint8Array

这些功能还与以下语言兼容:

//JS
console.log(decompress(compress('asdfasdfasdfasdf'))); //asdfasdfasdfasdf
//PHP
echo decompress(compress('asdfasdfasdfasdf')); //asdfasdfasdfasdf

对于JS,这在NodeJ中是开箱即用的。在浏览器环境中,您将需要Buffer的polyfil。

对于PHP,请记住安装Zlib扩展名。

答案 2 :(得分:0)

这似乎有效(下图)

涉及的步骤:

服务器端(php):

1)gzdeflate using ZLIB_ENCODING_DEFLATE option

2)base64_encode

客户端:(jScript)

1)atob

2)pako.ungzip

3)atos function

<script src='//cdnjs.cloudflare.com/ajax/libs/pako/1.0.5/pako_deflate.js' type='text/javascript'></script>

<script type='text/javascript'>
const compressedDEFLATE = '<?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(compressedDEFLATE)  ) )  );
</script>