如何从PHP服务器获取$ .ajax的zip [英] how to get a zip with $.ajax from php server
问题描述
我正在尝试在jquery的$ .ajax请求时发送由php服务器生成的zip。
I'm trying to send a zip generated by a php server when requested by jquery's $.ajax.
这是我的代码:
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:
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');
}
}
);
会发生什么:
- 服务器创建我要求的zip文件,并且该文件没有损坏。它包含,其中包括shouldBeThere.json。
- 服务器将数据发送到前端。
- console.log(data);通过使用文本编辑器打开在服务器上创建的zip文件,javascript中的行打印出与我所获得的字符串几乎完全相同的字符串。
- console.log(data.length); javascript中的行根据chrome的devtools打印一个小于响应头的内容长度的数字。也许是对数据损坏的暗示。
- saveAs创建一个包含其意图的文件的zip,使用正确的名称,但是当我尝试解压缩时,7zip显示错误:尝试是为了在文件开头之前移动文件指针。
6.JSZip似乎加载数据但是zip.file('shouldBeThere.json')为空。
- The server creates the zip file I ask it to, and this file isn't corrupted. It contains, among others, shouldBeThere.json.
- The server sends data to the frontend.
- The console.log(data); line in javascript prints a string almost identical from what I get by opening the zip file created on the server with a text editor.
- The console.log(data.length); line in javascript prints a number smaller than the content length of the response header according to chrome's devtools. Maybe a hint to a data corruption.
- saveAs creates a zip containing the file it's meant to, with the right name, but when I try to unzip it 7zip shows an error: "an attempt was made to move the file pointer before the beginning of the file". 6.JSZip seems to load the data but then zip.file('shouldBeThere.json') is null.
问题是我不知道问题是来自php还是来自javascript。我不知道php是否发送了损坏的zip或者javascript没有正确读取它。
The problem is I have no idea if the problem comes from php or from javascript. I don't know if php is sending a corrupted zip or if javascript isn't reading it right.
我已经尝试了所有的PHP头文件组合和方法我已经在互联网上找到。我还尝试在javascript中做不同的事情:使用ArrayBuffer而不是Uint8Array,使用Blob()中的{type:application / octet-stream}将字节而不是数据传递给zip.load()。
I have tried all the php headers combinations and methods i've found on the internet. I have also tried to do things differently in javascript: using an ArrayBuffer instead of Uint8Array, passing bytes instead of data to zip.load(), using {type: "application/octet-stream"} in Blob().
推荐答案
我终于找到了一个解决方案:必须指定ajax接收的数据类型,然后将此unicode数据转换为字符。这是我的新javascript代码:
I finally found a solution: It has to be specified to ajax the received data type, and then convert this unicode data into characters. Here is my new javascript code:
$.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<newContent.length; i++) { //modified
bytes[i] = newContent.charCodeAt(i); //modified
}
blob = new Blob([bytes], {type: "application/zip"})
saveAs(blob, "test.zip");
zip.load(newContent); //modified
jsonData = JSON.parse(zip.file('shouldBeThere.json').asText());
},
error: function() {
alert('error');
}
}
);
我的PHP代码很好,它甚至没有标题。这是我需要的最小PHP代码:
My php code was fine, it even worked without headers. Here is the minimal php code I need:
$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服务器获取$ .ajax的zip的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!