使用javascript在web浏览器中解压缩csv文件

使用javascript在web浏览器中解压缩csv文件,javascript,browser,zlib,Javascript,Browser,Zlib,我想从web服务器下载压缩的csv文件,然后在浏览器中解压缩 到目前为止,我已经尝试使用pako和zlib在我的服务器上获取gzip文件,但出现了各种问题。试图解压unix gzip文件时,我不断收到错误的头消息 接下来,我尝试使用node在服务器上压缩文件,但目前遇到了这个错误 Uncaught Error: invalid file signature:,� 下面是我用来获取文件的命令: $.ajax({ type: "GET", url: 'public/pols_zlib.csv.gz

我想从web服务器下载压缩的csv文件,然后在浏览器中解压缩

到目前为止,我已经尝试使用
pako
zlib
在我的服务器上获取gzip文件,但出现了各种问题。试图解压unix gzip文件时,我不断收到错误的头消息

接下来,我尝试使用node在服务器上压缩文件,但目前遇到了这个错误

Uncaught Error: invalid file signature:,�
下面是我用来获取文件的命令:

$.ajax({ type: "GET", url: 'public/pols_zlib.csv.gz'})
  .done(function(d){
    var gunzip = new Zlib.Gunzip(d);
    plain = gunzip.decompress(); 
  });
我正在寻找在我的服务器上压缩文件并在浏览器中解压的方法。

通过谷歌搜索“php和js中的压缩和解压”告诉我:


您遇到了这个问题,因为ajax将以标题文本/html进行响应

也许这样的东西可以帮助你:


您不需要在服务器上gzip.csv文件(除非您的主要目标是节省服务器上的磁盘空间)。这个答案假设您的目标是减少将.csv文件下载到客户端所需的时间

正如Quentin上面提到的,所有现代web服务器都为您处理有线压缩。这意味着.csv文件(以及所有基于文本的文档)可以在发送到客户端之前进行压缩。然后,客户端(web浏览器)为您解压缩文件。为了确保这些功能正常工作,您可以使用类似的工具嗅探HTTP流量。此屏幕截图显示如何使用GZIP压缩此网页

为了确保使用压缩,服务器和客户端都需要使用HTTP头“公布”事实。在客户机上,这可以通过ajax实现,如下所示:

$.ajax({
  ...
  headers: { "Accept-Encoding" : "gzip" },
  ...
});
如果服务器启用了压缩,它将使用以下http头进行响应:

Content-Encoding: gzip
正如在Fiddler中看到的:

您可以阅读有关HTTP压缩的更多信息


最后,我建议打开/关闭HTTP压缩,并使用Fiddler对结果进行基准测试。

我相信我前面的答案很有价值,因此我在这里创建了一个单独的答案来解决这个更具体的用例。条件是:

  • 无法控制服务器
  • 上传前必须限制csv的文件大小
  • 服务器未使用gzip对csv进行编码
  • 我建议使用该库在客户端上用javascript解码gzip文件

    但是,gzip文件必须首先进行base64编码。以下linux命令将执行此操作:

    gzip -c file.csv | base64 > file.csv.gz.txt
    
    我建议使用.txt文件扩展名,以确保服务器像文本一样处理它

    因为我使用DataURI下载csv(见下文),所以您也可以在gzip之前对其进行base64编码,以保存在客户端上进行的操作。但是,它会增加文件大小(这是您试图避免的)

    一旦文件是gzip'd&base64'd,就可以上传到服务器。请注意,base64将增加大量开销,但这是必需的。在较小的文件中更明显:

    uncompressed:        91 kB
    compressed:          38 kB
    compressed + base64: 72 kB
    
    uncompressed:        8.2 MB
    compressed:          1.9 MB
    compressed + base64: 2.6 MB
    
    这是HTML标记。这是一个我已经测试过的工作示例

    
    工作示例
    $.ajax({
    url:“/file.csv.gz.txt”,
    缓存:false
    })
    .done(函数(b64文件){
    //$('body').append(b64文件);//调试
    var binary=JXG.decompress(b64file);
    $('#link').attr(“href”,“数据:text/csv;base64,”+btoa(二进制));
    });
    文件
    
    对于需要。使用这种方法,不需要使用base64编码,因此允许更小的文件大小。当不需要旧浏览器支持时,建议使用此解决方案

    下载并添加对的引用

    这是我已经测试过的HTML

    <html>
    <head>
        <title>Binary Example</title>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script src="~/Scripts/pako_inflate.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            var oReq = new XMLHttpRequest();
            oReq.open("GET", 'file.csv.gz?_=' + new Date().getTime(), true);
            oReq.responseType = "arraybuffer";
            oReq.onload = function (oEvent) {
                var arrayBuffer = oReq.response; // Note: not oReq.responseText
                if (arrayBuffer) {
                    var byteArray = new Uint8Array(arrayBuffer);
                    var data = pako.inflate(byteArray);
                    //$('body').append(String.fromCharCode.apply(null, new Uint16Array(data)));  // debug
                    $('#link').attr("href", "data:text/csv;base64," + btoa(String.fromCharCode.apply(null, new Uint16Array(data))));
                }
            };
            oReq.send(null);
        </script>
    </head>
    <body>
        <a id="link" download="file.csv">file</a>
    </body>
    </html> 
    
    
    二进制示例
    var oReq=新的XMLHttpRequest();
    open(“GET“,”file.csv.gz?='+new Date().getTime(),true);
    oReq.responseType=“arraybuffer”;
    oReq.onload=功能(oEvent){
    var arrayBuffer=oReq.response;//注意:不是oReq.responseText
    if(arrayBuffer){
    var byteArray=新的UINT8阵列(arrayBuffer);
    var数据=pako.充气(byteArray);
    //$('body').append(String.fromCharCode.apply(null,新Uint16Array(数据));//调试
    $('#link').attr(“href”,“数据:text/csv;base64,”+btoa(String.fromCharCode.apply(null,新UINT16数组(数据)));
    }
    };
    oReq.send(空);
    文件
    
    在HTTP级别进行压缩,让浏览器在后台处理解压缩。昆汀,这在ajax调用中到底是什么样子的?就像一堆压缩数据,响应头说它是压缩的。@Quentin这是否意味着我需要在提供压缩文件的服务器上更改某些内容?或者,我可以在javascript调用中设置它吗?在这种情况下,我不控制服务器选项,因此更改服务器发送文件的方式实际上不是一个选项。无论解决方案是什么,它都必须使用javascript。也许您需要一个服务器端脚本来生成一个具有正确头的HTTP响应,并将您的CSV文件写入响应流。您是否熟悉任何服务器端技术?不幸的是,以下问题的答案是导致无效文件签名问题的原因。在这种情况下,我无法控制服务器,我上载的文件需要小于一定的大小才能上载。这就是为什么所有的解压都必须在javascript中完成,而且我无法更改服务器的响应方式。在这种情况下,服务器不会使用正确的标题进行回复,这将使浏览器自动解压缩文件。另外,jquery不会设置accept encoding,错误消息是它是一个不安全的头。在这种情况下,来自另一个线程的响应可能就是您正在寻找的:It