我正在使用网络服务器在C中编写嵌入式设备。一项任务是从此设备下载文件。我想一次下载几个文件,所以我创建了一个ajax-request,它使用POST-Request和一堆文件名来返回一个zip文件(我自己在设备上创建这些zip文件)。一切正常,但在传输整个zip文件后会出现对话框save as
。
在服务器端,设备正在发送200 OK
- ,Content-Type: application/octet-stream
- 和Content-Disposition: attachment; filename="testzip.zip"
- 标头。
在客户端我使用这个javascript代码(来自stackoverlfow: Handle file download from ajax post):
function downloadFiles(filenames) {
var xhr = new XMLHttpRequest();
xhr.open('POST', /file-save/, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
if (this.status === 200) {
var filename = "test.zip";
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([this.response], { type: type });
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
};
xhr.send(filenames);
}
当传输整个文件时,到达if语句if (this.status === 200)
。如果文件的大小很小,则没有问题,因为用户没有意识到时间不足。但是,即使文件正在下载,用户也无法看到任何下载的大约50MB的文件。在我看来,原因是a.click()
,因为点击方法会影响下载的开始。
是否有可以帮助我解决问题或提示的sombody? 顺便说一句,jquery不是一个选项!。
感谢您的帮助
编辑:我的目标是在每个包含大文件的网页上下载文件,在那里我会看到一个包含要保存位置的对话框,我可以看到下载进度。
解决方案(来自Herr Derb的提示):
function downloadFiles(filenames) {
var xhr = new XMLHttpRequest();
xhr.open('POST', /file_save/, true);
xhr.onload = function () {
if (this.status === 200) {
var mydisp = xhr.getResponseHeader('Content-Disposition');
var save_response = xhr.responseText;
var var_json_format = JSON.parse(save_response);
/* check for errors */
if(var_json_format["error"]) {
return;
} else {
status = _.findWhere(var_json_format["link"], {id : 'status'}).value;
download_id = _.findWhere(var_json_format["link"], {id : 'download_id'}).value;
}
if(status != "active") {
return;
}
var filename = "test.zip";
var downloadUrl = "/file_save/" + download_id;
var a = document.createElement("a");
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
};
xhr.send(filenames);
return;
}
答案 0 :(得分:0)
您的第一个请求应该只在您的服务器上创建zip文件并返回一个链接来访问它。在客户端站点上收到该链接后,只需执行它即可。这样,一切都会按照您的意愿发生,因为它将是一个常规的文件下载。 并且很快下载完成后,您可以再次自由删除该文件。