Ответ 1
AJAX не предназначен для загрузки файлов. Выскажите новое окно со ссылкой для загрузки в качестве его адреса или выполните document.location = ...
.
У меня есть кнопка, а 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 на основе пользовательского ввода. После его создания я хочу, чтобы он запрашивал загрузку или принудительную загрузку (желательно силу). Я использую следующий script в конце файла php для загрузки файла. Если я запустил этот script в отдельный файл, он отлично работает.
$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 options = {
url: "request/url",//replace with your request url
type: "POST",//replace with your request type
data: parameters,//see above
context: document.body,//replace with your contex
success: function(data){
if (data) {
if (data.path) {
//Create an hidden iframe, with the 'src' attribute set to the created ZIP file.
var dlif = $('
<iframe/>
',{'src':data.path}).hide();
//Append the iFrame to the context
this.append(dlif);
} else if (data.error) {
alert(data.error);
} else {
alert('Something went wrong');
}
}
}
};
$.ajax(options);
"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');
}
});