如何从PHP服务器获取$ .ajax的zip

我正在尝试在jquery的$ .ajax请求时发送由php服务器生成的zip。

这是我的代码:

PHP:

$file = tempnam($a_folder_path, "zip"); $zip = new ZipArchive(); $zip->open($file, ZipArchive::OVERWRITE); $zip->addFile($path_to_json, 'data.json'); $zip->close(); rename($file, $file . '.zip'); $filename = basename($file . '.zip'); $filepath = $file . '.zip'; while (ob_get_level()) { ob_end_clean(); } header("Pragma: public"); header("Expires: 0"); header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0"); header("Content-Description: File Transfer"); header("Content-type: application/octet-stream"); header("Content-Disposition: attachment; filename=\"".$filename."\""); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($filepath)); ob_end_flush(); echo file_get_contents($filepath); //@readfile($filepath); 

JavaScript的:

 $.ajax( { url: myUrl, type: 'POST', data: { "leData" : "some_data" }, context: document.body, cache: false, success: function(data) { console.log(data); console.log(data.length); var bytes = new Uint8Array(data.length); for (var i=0; i<data.length; i++) { bytes[i] = data.charCodeAt(i); } blob = new Blob([bytes], {type: "application/zip"}) saveAs(blob, "test.zip");//trying to access data with FileSave.js zip.load(data);//trying to access data with JSZip.js jsonData = JSON.parse(zip.file('shouldBeThere.json').asText()); }, error: function() { alert('error'); } } ); 

怎么了:

  1. 服务器创建我要求的zip文件,并且此文件未损坏。 它包含,其中包括shouldBeThere.json。
  2. 服务器将数据发送到前端。
  3. console.log(数据); 通过使用文本编辑器打开在服务器上创建的zip文件,javascript中的行打印出与我所获得的字符串几乎完全相同的字符串。
  4. console.log(data.length); javascript中的行根据chrome的devtools打印一个小于响应头的内容长度的数字。 也许暗示数据损坏。
  5. saveAs使用正确的名称创建一个包含其意图文件的zip,但是当我尝试解压缩时,7zip显示错误:“尝试在文件开头之前移动文件指针”。 6.JSZip似乎加载数据但是zip.file(’shouldBeThere.json’)为空。

问题是我不知道问题是来自php还是来自javascript。 我不知道php是否发送了损坏的zip或者javascript没有正确读取它。

我已经尝试了我在互联网上找到的所有php标题组合和方法。 我还尝试在javascript中做不同的事情:使用ArrayBuffer而不是Uint8Array,使用Blob()中的{type:“application / octet-stream”}将字节而不是数据传递给zip.load()。

我终于找到了一个解决方案:必须指定ajax接收的数据类型,然后将此unicode数据转换为字符。 这是我的新javascript代码:

 $.ajax( { url: myUrl, type: 'POST', data: { "leData" : "some_data" }, context: document.body, cache: false, dataType: 'text', //solution code mimeType: 'text/plain; charset=x-user-defined', //solution code success: function(data) { console.log(data); console.log(data.length); newContent = ""; //solution code for (var i = 0; i < data.length; i++) { //solution code newContent += String.fromCharCode(data.charCodeAt(i) & 0xFF); //solution code } var bytes = new Uint8Array(newContent.length); //modified for (var i=0; i 

我的PHP代码很好,甚至没有标题。 这是我需要的最小PHP代码:

  $file = tempnam($a_folder_path, "zip"); $zip = new ZipArchive(); $zip->open($file, ZipArchive::OVERWRITE); $zip->addFile($path_to_json, 'data.json'); $zip->close(); rename($file, $file . '.zip'); echo file_get_contents($file . '.zip'); 

解决方案受此启发

我正在寻找以下问题的解决方案:“在php url上发送请求,用于创建目录的zip并使用ajax响应下载它。”

以下代码有效:

用于zip的PHP部分:

 // Function for creating a zip of a directory function zipFilesAndDownload($directory, $file_names) { $zip = new ZipArchive(); if ($zip->open("../temp/$directory.zip", ZIPARCHIVE::CREATE) !== TRUE) { exit("Error on creating '../temp/$directory.zip'"); } foreach ($file_names as $file) { $zip->addFile($file, substr($file, strrpos($file, "/") + 1)); } $zip->close(); readfile("../temp/$directory.zip"); unlink("../temp/$directory.zip"); } // Code for creating array of filenames $directory = $_POST['directory']; // eg a directory with ID "123" $dirToZip = "../uploaddir/$directory"; if ($handle = opendir($dirToZip)) { $file_names = array(); while (($file = readdir($handle)) !== false) { if ($file != "." && $file != "..") { array_push($file_names, "$dirToZip/$file"); } } closedir($handle); zipFilesAndDownload($directory, $file_names); } 

JS部分:

  $(document).on('click', '#downloadDirectory', function () { var directory = '123'; $.ajax({ type: 'POST', url: '../createZip.php', data: {"directory": directory}, dataType: 'text', mimeType: 'text/plain; charset=x-user-defined', success: function (data) { var bytes = new Uint8Array(data.length); for (var i = 0; i < data.length; i++) { bytes[i] = data.charCodeAt(i); } blob = new Blob([bytes], {type: "application/zip"}) saveAs(blob, "pictures.zip"); // "saveAs" function is provided in FileSaver.js } }); });