Я хочу отправить «запрос на загрузку ajax», когда нажимаю кнопку, поэтому попробовал вот так:
javascript:
var xhr = new XMLHttpRequest();
xhr.open("GET", "download.php");
xhr.send();
download.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");
?>
но работает не так, как ожидалось, как мне это сделать? заранее спасибо
location.href='download.php';
Ответы:
Обновление 27 апреля 2015 г.
На сцену HTML5 приходит атрибут загрузки . Он поддерживается в Firefox и Chrome и скоро появится в IE11. В зависимости от ваших потребностей вы можете использовать его вместо запроса AJAX (или использования
window.location
), если файл, который вы хотите загрузить, находится в том же источнике, что и ваш сайт.Вы всегда можете сделать запрос AJAX /
window.location
откат, используя некоторый JavaScript, чтобы проверить,download
поддерживается ли он, а если нет, переключив его на вызовwindow.location
.Оригинальный ответ
Запрос AJAX не может открывать окно загрузки, так как вам физически нужно перейти к файлу, чтобы запросить загрузку. Вместо этого вы можете использовать функцию успеха для перехода к download.php. Откроется запрос на загрузку, но текущая страница не изменится.
$.ajax({ url: 'download.php', type: 'POST', success: function() { window.location = 'download.php'; } });
Несмотря на то, что это отвечает на вопрос, лучше просто использовать
window.location
и полностью избегать запроса AJAX.источник
Чтобы браузер скачал файл, вам нужно сделать такой запрос:
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(); }
источник
<a>
тег с помощью JS "на лету", но нужно добавить егоdocument.body
. Вы, безусловно, хотите одновременно это скрыть.На самом деле вам вообще не нужен ajax. Если вы просто установите "download.php" в качестве href на кнопке, или, если это не ссылка, используйте:
window.location = 'download.php';
Браузер должен распознавать двоичную загрузку и не загружать фактическую страницу, а просто использовать файл как загрузку.
источник
window.location
является JavaScript.Кроссбраузерное решение, протестировано в 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.setRequestHeader('my-custom-header', 'custom-value'); // adding some headers (if needed) 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();
источник
Authorization
?window.URL.revokeObjectURL(el.href);
послеel.click()
?Это возможно. Вы можете начать загрузку изнутри функции ajax, например, сразу после создания файла .csv.
У меня есть функция ajax, которая экспортирует базу данных контактов в файл .csv, и сразу после ее завершения автоматически запускает загрузку файла .csv. Итак, после того, как я получил responseText и все в порядке, я перенаправляю браузер следующим образом:
window.location="download.php?filename=export.csv";
Мой файл download.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
источник
я предпочитаю
location.assign(url);
Полный пример синтаксиса:
document.location.assign('https://www.urltodocument.com/document.pdf');
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]*=((['"]).*?\2|[^;\n]*)/; var matches = filenameRegex.exec(disposition); if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, ''); }
источник
Это решение не сильно отличается от приведенных выше, но для меня оно работает очень хорошо и чисто.
Я предлагаю base64 кодировать сторону файлового сервера (base64_encode (), если вы используете PHP) и отправлять данные в кодировке base64 клиенту.
На клиенте вы делаете это:
let blob = this.dataURItoBlob(THE_MIME_TYPE + "," + response.file); let uri = URL.createObjectURL(blob); let link = document.createElement("a"); link.download = THE_FILE_NAME, link.href = uri; document.body.appendChild(link); link.click(); document.body.removeChild(link);
Этот код помещает закодированные данные в ссылку и имитирует щелчок по ссылке, а затем удаляет ее.
источник
Ваши потребности покрываются
window.location('download.php');
Но я думаю, что вам нужно передать файл для загрузки, а не всегда загружать тот же файл, и поэтому вы используете запрос, один из вариантов - создать файл php так же просто, как showfile.php и сделать запрос вроде
var myfile = filetodownload.txt var url = "shofile.php?file=" + myfile ; ajaxRequest.open("GET", url, true);
showfile.php
<?php $file = $_GET["file"] echo $file;
где file - это имя файла, переданное через Get или Post в запросе, а затем просто перехватить ответ в функции.
if(ajaxRequest.readyState == 4){ var file = ajaxRequest.responseText; window.location = 'downfile.php?file=' + file; } }
источник
есть еще одно решение для загрузки веб-страницы в ajax. Но я имею в виду страницу, которую нужно сначала обработать, а затем загрузить.
Для начала нужно отделить обработку страницы от загрузки результатов.
1) В вызове ajax выполняются только расчеты страницы.
Надеюсь, это решение может быть полезно многим, как и мне.
источник
Для тех, кто ищет более современный подход, вы можете использовать
fetch API
. В следующем примере показано, как загрузить файл электронной таблицы. Это легко сделать с помощью следующего кода.fetch(url, { body: JSON.stringify(data), method: 'POST', headers: { 'Content-Type': 'application/json; charset=utf-8' }, }) .then(response => response.blob()) .then(response => { const blob = new Blob([response], {type: 'application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}); const downloadUrl = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = downloadUrl; a.download = "file.xlsx"; document.body.appendChild(a); a.click(); })
Я считаю, что этот подход намного легче понять, чем другие
XMLHttpRequest
решения. Кроме того, он имеет синтаксис, аналогичныйjQuery
подходу, без необходимости добавлять какие-либо дополнительные библиотеки.Конечно, я бы посоветовал проверить, для какого браузера вы разрабатываете, поскольку этот новый подход не будет работать в IE. Вы можете найти полный список совместимых браузеров по следующей ссылке .
Важно : в этом примере я отправляю запрос JSON на сервер, который прослушивает данный
url
. Этоurl
должно быть установлено, на моем примере я предполагаю, что вы знаете эту часть. Также обратите внимание на заголовки, необходимые для работы вашего запроса. Поскольку я отправляю JSON, я должен добавитьContent-Type
заголовок и установить егоapplication/json; charset=utf-8
, чтобы сервер знал, какой тип запроса он получит.источник
Решение @Joao Marcos работает для меня, но мне пришлось изменить код, чтобы он работал в IE, ниже, если как выглядит код
downloadFile(url,filename) { var that = this; const extension = url.split('/').pop().split('?')[0].split('.').pop(); var req = new XMLHttpRequest(); req.open("GET", url, true); req.responseType = "blob"; req.onload = function (event) { const fileName = `${filename}.${extension}`; const blob = req.response; if (window.navigator.msSaveBlob) { // IE window.navigator.msSaveOrOpenBlob(blob, fileName); } const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = fileName; link.click(); URL.revokeObjectURL(link.href); }; req.send(); },
источник