0

我正在尝试结合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 进行膨胀?

到目前为止,我已经尝试添加从 1 到 9 的各种 gzdeflate “级别”,但它们似乎都没有任何区别。在这一点上,我只是在猜测。

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

非常感谢您。

4

4 回答 4

3

更新到@edwardsmarkf 的答案,您现在可以在没有 atos 功能的情况下解决这个问题。大多数较新的浏览器都有TextDecoder api。你可以像这样使用它:

const decoder = new TextDecoder();
const result = decoder.decode(pako.ungzip(atob(compressedBase64Data)));
于 2019-05-31T05:32:01.723 回答
2

我无法在这里得到答案,所以我做了一些研究。

正如这里PleaseStand所指出的,问题在于 PHP 使用 UTF-8 字符串,而 JS 使用 UTF-16 字符串。因此,二进制字符串到 base64 字符串编码会有所不同。

我使用的解决方案是强制 JS 将数据解释为 UTF-8。这很简单,因为pako接受并返回Uint8Arrays,它们本质上是 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实例也是Uint8Array实例,因此我们不需要在将其提供给 pako 之前将其转换Buffer为 a 。Uint8Array

这些功能在语言中也兼容:

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

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

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

于 2019-10-06T10:01:21.110 回答
0

我对php不熟悉,所以我有点为这个问题苦苦挣扎,所以我想在php中发布一个最小的工作解决方案:

$response = gzdeflate('My data', 9, ZLIB_ENCODING_DEFLATE);

header('Content-Encoding: deflate');
echo $response;

之后不用再使用pako,数据会被浏览器解压。

例如,如果您请求 json 格式的数据:

$.ajax({
    type: 'GET',
    url: 'http://target.com',
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    headers : {'Accept-Encoding': 'deflate '},
})
.done(function(res) {
    console.log(res)
})
.fail(function(xhr, textStatus, errorThrown) {
});
于 2021-08-17T14:01:29.997 回答
0

这似乎有效(下)

涉及的步骤:

服务器端(php):

1) gzdeflate 使用 ZLIB_ENCODING_DEFLATE 选项

2) base64_encode

客户端:(jScript)

1)阿托布

2) pako.ungzip

3)atos函数

<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>
于 2017-06-21T18:55:23.203 回答