2016-08-29 2 views
0

Я программирую встроенное устройство на 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; 
} 
+0

Вы можете использовать Ajax, как определено в вопросе, который вы связали. А в ajax вместо 'success:' вы можете использовать 'complete:', который вызывается, когда запрос ajax будет завершен. –

+0

но я прав, это jquery-решение? – Chris

+0

да, согласно моим знаниям, вы правы –

ответ

0

Ваш первый запрос должен создать только почтовый файл на сервере и возвращает ссылку, чтобы достичь ее. После того, как вы получили эту ссылку на клиентском сайте, просто выполните ее. Таким образом, все будет происходить по вашему желанию, так как это будет обычная загрузка файла. И скоро загрузка закончится, и вы сможете снова удалить файл.

+0

ОК, я попробую.Но я должен создать zip-файл динамически, потому что у меня недостаточно хранилища для создания большого файла. Возможно, я смогу разработать обходное решение. – Chris

+0

Наилучшим способом является то, что вы просто показываете загрузчик до тех пор, пока не будет завершен вызов ajax. Дело в том, что вы никогда не узнаете размер загрузки во время этого. –