У меня есть кнопка и onclick
она вызовет функцию ajax.
Вот моя функция ajax
function csv(){ ajaxRequest = ajax();//ajax() is function that has all the XML HTTP Requests postdata = "data=" + document.getElementById("id").value; ajaxRequest.onreadystatechange = function(){ var ajaxDisplay = document.getElementById('ajaxDiv'); if(ajaxRequest.readyState == 4 && ajaxRequest.status==200){ ajaxDisplay.innerHTML = ajaxRequest.responseText; } } ajaxRequest.open("POST","csv.php",false); ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); ajaxRequest.send(postdata); }
Я создаю файл csv на основе ввода пользователя. После его создания я хочу, чтобы он запрашивал загрузку или принудительную загрузку (желательно силу). Я использую следующий скрипт в конце файла php для загрузки файла. Если я запустил этот скрипт в отдельном файле, он отлично работает.
$fileName = 'file.csv'; $downloadFileName = 'newfile.csv'; if (file_exists($fileName)) { header('Content-Description: File Transfer'); header('Content-Type: text/csv'); header('Content-Disposition: attachment; filename='.$downloadFileName); ob_clean(); flush(); readfile($fileName); exit; } echo "done";
Но если я запустил его в конце csv.php, он выведет содержимое файла .csv на страницу (в ajaxDiv) вместо загрузки.
Есть ли способ принудительно загрузить файл в конце csv.php?
AJAX не предназначен для загрузки файлов. Выскажите новое окно со ссылкой для загрузки в качестве его адреса или сделайте document.location = ...
Очень простое решение с использованием jQuery:
на стороне клиента:
$('.act_download_statement').click(function(e){ e.preventDefault(); form = $('#my_form'); form.submit(); });
и на стороне сервера убедитесь, что вы отправили правильный заголовок Content-Type
, поэтому браузер узнает его вложение и начнется загрузка.
Я сделал это со скрытым iframe. Я использую perl, а не php, поэтому просто дадим концепцию, а не кодовое решение.
Клиент отправляет запрос Ajax на сервер, вызывая создание содержимого файла. Это сохраняется как временный файл на сервере, и имя файла возвращается клиенту.
Клиент (javascript) получает имя файла и устанавливает iframe src на некоторый url, который будет доставлять файл, например:
$('iframe_dl').src="/app?download=1&filename=" + the_filename
Сервер вырывает файл, отключает его и отправляет поток клиенту с этими заголовками:
Content-Type:'application/force-download' Content-Disposition:'attachment; filename=the_filename'
Работает как шарм.
@joe: Большое спасибо, это был хороший хедз-ап!
У меня была немного сложнее проблема: 1. отправка запроса AJAX с данными POST, для получения сервером ZIP-файла 2. получение ответа назад 3. загрузка ZIP-файла
Так вот как я это сделал (используя JQuery для обработки запроса AJAX):
Первоначальный почтовый запрос:
var parameters = { pid : "mypid", "files[]": ["file1.jpg","file2.jpg","file3.jpg"] }
var parameters = { pid : "mypid", "files[]": ["file1.jpg","file2.jpg","file3.jpg"] }
var options = {
url: "request / url", // заменить URL вашего запроса
type: «POST», // заменяем ваш тип запроса
данные: параметры, // см. выше
context: document.body, // заменить на ваш contex
успех: функция (данные) {
if (data) {
if (data.path) {
// Создаем скрытый iframe с атрибутом 'src', установленным в созданный ZIP-файл.
var dlif = $ (' <iframe/>
', {'src': data.path}). hide ();
// Добавить iFrame в контекст
this.append (dlif);
} else if (data.error) {
оповещения (data.error);
} else {
предупреждение («Что-то пошло не так»);
}
}
}
};
$ .ajax (варианты);
«Request / url» обрабатывает создание zip (отключено от темы, поэтому я не буду публиковать полный код) и возвращает следующий объект JSON. Что-то вроде:
//Code to create the zip file //...... //Id of the file $zipid = "myzipfile.zip" //Download Link - it can be prettier $dlink = 'http://'.$_SERVER["SERVER_NAME"].'/request/download&file='.$zipid; //JSON response to be handled on the client side $result = '{"success":1,"path":"'.$dlink.'","error":null}'; header('Content-type: application/json;'); echo $result;
«Запрос / загрузка» может выполнять некоторые проверки безопасности, если необходимо, и генерировать передачу файлов:
$fn = $_GET['file']; if ($fn) { //Perform security checks //.....check user session/role/whatever $result = $_SERVER['DOCUMENT_ROOT'].'/path/to/file/'.$fn; if (file_exists($result)) { header('Content-Description: File Transfer'); header('Content-Type: application/force-download'); header('Content-Disposition: attachment; filename='.basename($result)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($result)); ob_clean(); flush(); readfile($result); @unlink($result); } }
Вы не можете загрузить файл напрямую через ajax.
Вы можете поместить ссылку на страницу с URL-адресом в ваш файл (возвращенный при вызове ajax), иначе можно использовать скрытый iframe
и динамически устанавливать URL-адрес источника этого iframe
. Таким образом, вы можете загрузить файл без обновления страницы.
Вот код
$.ajax({ url : "yourURL.php", type : "GET", success : function(data) { $("#iframeID").attr('src', 'downloadFileURL'); } });