Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/409.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AJAX响应提供了一个损坏的压缩(.tgz)文件_Javascript_Ajax_Compression_Download_Gunzip - Fatal编程技术网

Javascript AJAX响应提供了一个损坏的压缩(.tgz)文件

Javascript AJAX响应提供了一个损坏的压缩(.tgz)文件,javascript,ajax,compression,download,gunzip,Javascript,Ajax,Compression,Download,Gunzip,我们正在实现一个客户端web应用程序,它专门通过XMLHttpRequests(和AJAX引擎)与服务器通信 XHR响应通常是纯文本,上面有一些XML,但在本例中,服务器发送的是.tgz文件类型的压缩数据。我们确信服务器发送的数据是正确的,因为如果我们使用HTTP命令行客户端(如curl),作为响应发送的文件是有效的,并且包含预期的数据 但是,在进行AJAX调用并在可下载文件中“blobing”响应时,我们获得的文件与正确的文件大小不同(更高),解压缩程序无法识别该文件。它给出了以下错误: gz

我们正在实现一个客户端web应用程序,它专门通过XMLHttpRequests(和AJAX引擎)与服务器通信

XHR响应通常是纯文本,上面有一些XML,但在本例中,服务器发送的是.tgz文件类型的压缩数据。我们确信服务器发送的数据是正确的,因为如果我们使用HTTP命令行客户端(如curl),作为响应发送的文件是有效的,并且包含预期的数据

但是,在进行AJAX调用并在可下载文件中“blobing”响应时,我们获得的文件与正确的文件大小不同(更高),解压缩程序无法识别该文件。它给出了以下错误:

gzip: stdin: not in gzip format
/bin/gtar: Child returned status 1
/bin/gtar: Error is not recoverable: exiting now
我使用的代码如下所示:

*$.AJAX*.done(function(data){
    window.URL = window.webkitURL || window.URL;
    var contentType = 'application/x-compressed-tar';
    var file = new Blob([data], {type: contentType});
    var a = document.createElement('a'),
    ev = document.createEvent("MouseEvents");
    a.download = "browser_download2.tgz";
    a.href = window.URL.createObjectURL(file);
    ev.initMouseEvent("click", true, false, self, 0, 0, 0, 0, 0,
            false, false, false, false, 0, null);
    a.dispatchEvent(ev);
});
我避免使用用于进行AJAX调用的参数,但假设这不是问题所在,因为我正确地收到了答案。我使用了这个contentType,因为它与通过curl获得的显示的内容相同,但我尝试了不同的内容。代码可能看起来有点奇怪,所以我将为您脱色:我基本上是在创建一个链接,并在其上附加下载链接和文件名(命名文件的方式很肮脏)。最后,我几乎点击了链接

我比较了正确的tgz文件和通过浏览器通过十六进制查看器获得的文件,并观察到损坏的文件(EF、BF和BD,整个文件)中重复的模式在正确的文件中不存在

因此,我想到了一些可能的原因:

(a) 浏览器正在添加额外字符或可能是响应 头仍然在下载的文件中

(b) 文件已部分解压缩,因为当我检查 请求头我可以声明“接受编码:gzip,deflate”; 虽然我不知道浏览器(在我的例子中是Firefox) 自动解压缩数据

(c) 我用来阻塞数据的代码不正确;虽然 它在另一个文件中使用纯文本文件很好地实现了aim 时机

编辑

我还向您提供了hex检查的链接:

(a) 损坏的文件:
(b) (大概)正确的文件:

我不知道这个线程是否对某人有帮助,但以防万一,我找到了问题的原因和可能的解决方案

原因

默认Javascript变量以Unicode/ASCII格式存储信息;他们没有准备好正确存储二进制数据,这就是为什么人们很容易看到错误的字符被解释(这也解释了为什么在十六进制查看器中观察到重复EF、BF等,代表错误的ASCII/Unicode字符)

解决方案

最新的浏览器版本实现了所谓的类型化数组。它们是javascript数组,可以存储不同格式(也是二进制)的数据。然后,如果指定XMLHttpRequest响应为二进制格式,则数据将正确存储,并且在将数据填充到文件中时,文件不会损坏。查看我使用的代码:

var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = 'arraybuffer';

请注意,关键点是将responseType定义为“arraybuffer”。注意到我决定不再将Jquery用于AJAX,这可能也很有趣。它没有很好地实现这个特性,我解析Jquery的所有尝试都是徒劳的(在我的例子中,其他地方描述的OverrideMemetype无效)。相反,旧的普通XMLHttRquest工作得非常好

2015年仍然有用!我可以确认,在2019年,jQuery 3.3.1仍然如此,并且这个答案仍然有效。