我有一个PHP代码,该代码可生成一个zip文件,并使其可从浏览器下载。下载部分如下:
download.php
// force client download
if (headers_sent()) {
echo 'HTTP header already sent';
} else {
if (!is_file($zipFile)) {
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
echo $zipFile . ' not found';
} else if (!is_readable($zipFile)) {
header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
echo $zipFile . ' not readable';
} else {
ob_start();
// http headers for zip downloads
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . $zipName . '"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
set_time_limit(0);
ob_flush();
ob_clean();
readfile($zipFile);
}
}
直接像localhost/download.php
这样从浏览器中调用时,它的工作原理使我可以正确下载压缩文件。
但是,我需要从JS Web应用程序中调用它。
我调用它的方式是通过如下所示的POST AJAX请求:
var xhr;
if (window.XMLHttpRequest) xhr = new XMLHttpRequest(); // all browsers
else xhr = new ActiveXObject("Microsoft.XMLHTTP"); // for IE
var php_url = '/localhost/download.php' // ?wfs_url=' + url + 'format=' + format_list[0];
// (https://stackoverflow.com/a/53982364/1979665)
var formData = new FormData();
formData.append('wfs_url', url);
formData.append('format', format_list[0]);
xhr.open('POST', php_url);
xhr.onreadystatechange = function () {
if (xhr.readyState===4 && xhr.status===200) {
alert('Server reply: ' + xhr.responseText);
}
}
xhr.send(formData);
return false;
当我点击一个按钮时,代码被触发。
显然,它在做“某事”。 PHP中间输出(某些文件夹)已正确创建,但下载未开始。
alert('Server reply: ' + xhr.responseText);
部分显示了一条带有一些凌乱符号的奇怪消息,我猜这是从创建的文件中获得的,并以某种方式将其读取为文本。
这是消息的屏幕截图:
答案 0 :(得分:2)
PHP脚本正在发送zip文件的实际二进制源,而AJAX请求正尝试将其显示为文本,这就是您得到的垃圾。
如果您真的想保留AJAX(将<form>
发送到download.php
会更简单),则可以做两件事:
只需在PHP中将URL打印到$zipFile
,然后当您使用window.location.href=xhr.responseText;
将响应重定向到它时即可。
将响应另存为zip文件。参见How to save binary data of zip file in Javascript?
答案 1 :(得分:0)
按照@Gabriel的选项2接受答案后,我能够使我的代码正常工作。这是JS的修改版本(我没有对PHP代码进行任何更改):
var php_url = '/localhost/download.php' // ?wfs_url=' + url + 'format=' + format_list[0];
// (https://stackoverflow.com/a/53982364/1979665)
var formData = new FormData();
formData.append('wfs_url', url);
formData.append('format', format_list[0]);
xhr.open('POST', php_url);
xhr.onreadystatechange = function () {
if (xhr.readyState===4 && xhr.status===200) {
var blob = new Blob([xhr.response], { // SOLUTION
type: "application/zip", // SOLUTION
}); // SOLUTION
var filename = "test.zip"; // SOLUTION
if (navigator.msSaveOrOpenBlob) { // SOLUTION
navigator.msSaveOrOpenBlob(blob, filename); // SOLUTION
} else { // SOLUTION
var a = document.createElement("a"); // SOLUTION
document.body.appendChild(a); // SOLUTION
a.style = "display:none"; // SOLUTION
var url = window.URL.createObjectURL(blob); // SOLUTION
a.href = url; // SOLUTION
a.download = filename; // SOLUTION
a.click(); // SOLUTION
window.URL.revokeObjectURL(url); // SOLUTION
a.remove(); // SOLUTION
} // SOLUTION
}
}
xhr.responseType = "arraybuffer"; // SOLUTION
xhr.send(formData);