скачать файл с помощью AJAX-запроса


Я хочу отправить "ajax запрос на загрузку" , когда я нажимаю на кнопку, поэтому я попытался таким образом:

javascript:

var xhr = new XMLHttpRequest();
xhr.open("GET", "download.php");
xhr.send();

скачать.php:

<?
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename= file.txt");
header("Content-Transfer-Encoding: binary");    
readfile("file.txt");
?>

но не работает, как ожидалось, как я могу это сделать ? Заранее спасибо

7 67

7 ответов:

Обновление 27 Апреля 2015

вверх и подходит к сцене HTML5 является скачать атрибут. Это поддерживает в Firefox и Chrome, и скоро придет к IE11. В зависимости от ваших потребностей, вы можете использовать его вместо запроса AJAX (или с помощью window.location) до тех пор, пока файл, который вы хотите загрузить, находится в том же источнике, что и ваш сайт.

вы всегда можете сделать запрос AJAX/window.location резервной с помощью некоторые JavaScript чтобы проверить, если download поддерживается, и если нет, переключение его на вызов window.location.

оригинальный ответ

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

$.ajax({
    url: 'download.php',
    type: 'POST',
    success: function() {
        window.location = 'download.php';
    }
});

хотя это и отвечает на вопрос, лучше просто использовать window.location и полностью избежать запроса AJAX.

на самом деле вам вообще не нужен ajax для этого. Если вы просто установите "скачать.php " в качестве href на кнопке, или, если это не ссылка использовать:

window.location = 'download.php';

браузер должен распознавать двоичную загрузку и не загружать фактическую страницу, а просто обслуживать файл в качестве загрузки.

чтобы браузер загрузил файл, вам нужно сделать запрос следующим образом:

 function downloadFile(urlToSend) {
     var req = new XMLHttpRequest();
     req.open("GET", urlToSend, true);
     req.responseType = "blob";
     req.onload = function (event) {
         var blob = req.response;
         var fileName = req.getResponseHeader("fileName") //if you have the fileName header available
         var link=document.createElement('a');
         link.href=window.URL.createObjectURL(blob);
         link.download=fileName;
         link.click();
     };

     req.send();
 }

это возможно. Вы можете запустить загрузку из функции ajax, например, сразу после нее .создается csv-файл.

у меня есть функция ajax, которая экспортирует базу данных контактов в a .csv-файл, и сразу после его завершения, он автоматически запускает .загрузка файла csv. Итак, после того, как я получаю responseText и все в порядке, я перенаправляю браузер следующим образом:

window.location="download.php?filename=export.csv";

мой скачать.php файл выглядит так это:

<?php

    $file = $_GET['filename'];

    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Disposition: attachment; filename=".$file."");
    header("Content-Transfer-Encoding: binary");
    header("Content-Type: binary/octet-stream");
    readfile($file);

?>

там нет обновления страницы вообще и файл автоматически начинает загрузку.

Примечание - протестировано в следующих браузерах:

Chrome v37.0.2062.120 
Firefox v32.0.1
Opera v12.17
Internet Explorer v11

кросс-браузерное решение, протестированное на Chrome, Firefox, Edge, IE11.

в DOM добавьте скрытый тег ссылки:

<a id="target" style="display: none"></a>

затем:

var req = new XMLHttpRequest();
req.open("GET", downloadUrl, true);
req.responseType = "blob";

req.onload = function (event) {
  var blob = req.response;
  var fileName = null;
  var contentType = req.getResponseHeader("content-type");

  // IE/EDGE seems not returning some response header
  if (req.getResponseHeader("content-disposition")) {
    var contentDisposition = req.getResponseHeader("content-disposition");
    fileName = contentDisposition.substring(contentDisposition.indexOf("=")+1);
  } else {
    fileName = "unnamed." + contentType.substring(contentType.indexOf("/")+1);
  }

  if (window.navigator.msSaveOrOpenBlob) {
    // Internet Explorer
    window.navigator.msSaveOrOpenBlob(new Blob([blob], {type: contentType}), fileName);
  } else {
    var el = document.getElementById("target");
    el.href = window.URL.createObjectURL(blob);
    el.download = fileName;
    el.click();
  }
};
req.send();

Я предпочитаю место.назначить()

developer.mozilla.org/en-US/docs/Web/API/Location.assign

декодирование имени файла из заголовка немного сложнее...

    var filename = "default.pdf";
    var disposition = req.getResponseHeader('Content-Disposition');

    if (disposition && disposition.indexOf('attachment') !== -1) 
    {
       var filenameRegex = /filename[^;=\n]*=((['"]).*?|[^;\n]*)/;
       var matches = filenameRegex.exec(disposition);

       if (matches != null && matches[1]) 
           filename = matches[1].replace(/['"]/g, '');
    }