Javascript 通过ajax调用php下载文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6668776/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Download file through an ajax call php
提问by theking963
I have a button and onclick
it will call an ajax function.
我有一个按钮,onclick
它会调用一个 ajax 函数。
Here is my ajax function
这是我的 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);
}
I create the csv file based on the user input. After it's created I want it to prompt download or force download(preferably force). I am using the following script at the end of the php file to download the file. If I run this script in a separate file it works fine.
我根据用户输入创建了 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";
But If I run it at the end of csv.php it outputs the contents of the file.csv into the page(into the ajaxDiv) instead of downloading.
但是如果我在 csv.php 的末尾运行它,它会将 file.csv 的内容输出到页面(进入 ajaxDiv)而不是下载。
Is there a way to force download the file at the end of csv.php?
有没有办法在 csv.php 的末尾强制下载文件?
回答by Marc B
AJAX isn't for downloading files. Pop up a new window with the download link as its address, or do document.location = ...
.
AJAX 不用于下载文件。以下载链接为地址弹出一个新窗口,或执行document.location = ...
.
回答by blink281
A very simple solution using jQuery:
使用 jQuery 的一个非常简单的解决方案:
on the client side:
在客户端:
$('.act_download_statement').click(function(e){
e.preventDefault();
form = $('#my_form');
form.submit();
});
and on the server side, make sure you send back the correct Content-Type
header, so the browser will know its an attachment and the download will begin.
在服务器端,确保您发回正确的Content-Type
标头,这样浏览器就会知道它是一个附件并开始下载。
回答by Dario
@joe : Many thanks, this was a good heads up!
@joe:非常感谢,这是一个很好的提醒!
I had a slightly harder problem: 1. sending an AJAX request with POST data, for the server to produce a ZIP file 2. getting a response back 3. download the ZIP file
我遇到了一个稍微困难的问题:1. 发送带有 POST 数据的 AJAX 请求,以便服务器生成 ZIP 文件 2. 获得响应 3. 下载 ZIP 文件
So that's how I did it (using JQuery to handle the AJAX request):
所以我就是这样做的(使用 JQuery 处理 AJAX 请求):
Initial post request:
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);
初始发布请求:
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);
The "request/url" handles the zip creation (off topic, so I wont post the full code) and returns the following JSON object. Something like:
“请求/网址”处理 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;
The "request/download" can perform some security checks, if needed, and generate the file transfer:
如果需要,“请求/下载”可以执行一些安全检查,并生成文件传输:
$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);
}
}
回答by joe
I have accomplished this with a hidden iframe. I use perl, not php, so will just give concept, not code solution.
我已经用一个隐藏的 iframe 完成了这个。我使用 perl,而不是 php,所以只会给出概念,而不是代码解决方案。
Client sends Ajax request to server, causing the file content to be generated. This is saved as a temp file on the server, and the filename is returned to the client.
客户端向服务器发送 Ajax 请求,导致生成文件内容。这将作为临时文件保存在服务器上,并将文件名返回给客户端。
Client (javascript) receives filename, and sets the iframe src to some url that will deliver the file, like:
客户端 (javascript) 接收文件名,并将 iframe src 设置为将传递文件的某个 url,例如:
$('iframe_dl').src="/app?download=1&filename=" + the_filename
Server slurps the file, unlinks it, and sends the stream to the client, with these headers:
服务器 slurps 文件,取消链接,然后将流发送到客户端,其中包含以下标头:
Content-Type:'application/force-download'
Content-Disposition:'attachment; filename=the_filename'
Works like a charm.
奇迹般有效。
回答by Naimish B. Makwana
You can't download the file directly via ajax.
不能直接通过ajax下载文件。
You can put a link on the page with the URL to your file (returned from the ajax call) or another way is to use a hidden iframe
and set the URL of the source of that iframe
dynamically. This way you can download the file without refreshing the page.
您可以在页面上放置一个带有指向您的文件的 URL 的链接(从 ajax 调用返回),或者另一种方法是使用隐藏iframe
并iframe
动态设置该源的 URL 。这样您就可以在不刷新页面的情况下下载文件。
Here is the code
这是代码
$.ajax({
url : "yourURL.php",
type : "GET",
success : function(data) {
$("#iframeID").attr('src', 'downloadFileURL');
}
});