Я программирую встроенное устройство на C с веб-сервером. Одна задача - загрузить файлы с этих устройств. Я хочу загрузить серверные файлы сразу, поэтому я создал ajax-запрос, который использует POST-Request и кучу имен файлов, чтобы вернуть zip-файл (я создаю этот zip-файл самостоятельно на устройстве). Все работает нормально, но диалог save as
появляется после передачи всего zip-файла.ajax -> сохранить как диалог перед загрузкой
На стороне сервера устройство отправляет 200 OK
-, Content-Type: application/octet-stream
- и Content-Disposition: attachment; filename="testzip.zip"
-headers.
На клиентской стороне я, используя этот 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 (this.status === 200)
достигается, когда передается весь файл. Если размер файла мал, проблема не возникает, потому что пользователь не признает нехватку времени. Но файл размером около 50 МБ пользователь не может видеть никакой загрузки, хотя файл загружается. По-моему, причина a.click()
, потому что метод click-imitades начинает загрузку.
Есть ли кто-нибудь, кто может помочь мне с решением или некоторыми подсказками? Кстати, jquery не вариант !.
Спасибо за любую помощь
EDIT: моя цель состоит в том, чтобы загрузить файл, как на каждой странице с большими файлами, где я получаю диалог с местом, чтобы сохранить и я могу видеть загрузки-прогресс.
РЕШЕНИЕ (Подсказка от 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;
}
Вы можете использовать Ajax, как определено в вопросе, который вы связали. А в ajax вместо 'success:' вы можете использовать 'complete:', который вызывается, когда запрос ajax будет завершен. –
но я прав, это jquery-решение? – Chris
да, согласно моим знаниям, вы правы –