【问题标题】:using php-gzdeflate and pako-js使用 php-gzdeflate 和 pako-js
【发布时间】:2017-11-23 10:46:33
【问题描述】:

我正在尝试合并 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 扩展

非常感谢。

【问题讨论】:

    标签: javascript php pako


    【解决方案1】:

    我不熟悉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) {
    });
    

    【讨论】:

      【解决方案2】:

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

      正如PleaseStand 指出的here,问题在于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 instances are also Uint8Array instances,因此我们不需要在将 Buffer 转换为 Uint8Array 之前将其提供给 pako。

      这些功能也兼容多种语言:

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

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

      对于 PHP,记得安装 Zlib 扩展。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

          这似乎有效(下)

          涉及的步骤:

          服务器端 (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>
          

          【讨论】:

            猜你喜欢
            • 2018-03-03
            • 1970-01-01
            • 1970-01-01
            • 2017-11-04
            • 2013-09-15
            • 2020-07-10
            • 1970-01-01
            • 2016-04-17
            • 2013-03-20
            相关资源
            最近更新 更多