通过ajax调用php下载文件

the*_*963 32 javascript php ajax download

我有一个按钮,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);
}
Run Code Online (Sandbox Code Playgroud)

我根据用户输入创建了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";
Run Code Online (Sandbox Code Playgroud)

但是如果我在csv.php的末尾运行它,它会将file.csv的内容输出到页面(进入ajaxDiv)而不是下载.

有没有办法强制下载csv.php末尾的文件?

Mar*_*c B 40

AJAX不用于下载文件.弹出一个新窗口,下载链接作为其地址,或者执行document.location = ....

  • 我认为技术上最好设置`window.location`; 看到这个讨论:http://stackoverflow.com/questions/7857878/window-location-vs-document-location (17认同)
  • 为什么 AJAX 不用于下载文件? (2认同)

小智 20

一个使用jQuery的简单解决方案:

在客户端:

$('.act_download_statement').click(function(e){
    e.preventDefault();
    form = $('#my_form');
    form.submit();
});
Run Code Online (Sandbox Code Playgroud)

在服务器端,确保发回正确的Content-Type标题,以便浏览器知道它的附件并开始下载.


小智 12

@joe:非常感谢,这是一个很好的抬头!

我有一个稍微难点的问题:1.发送带有POST数据的AJAX请求,服务器生成ZIP文件2.获得响应3.下载ZIP文件

这就是我做的方式(使用JQuery来处理AJAX请求):

  1. 初始职位要求:

    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);

    Run Code Online (Sandbox Code Playgroud)

"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;
Run Code Online (Sandbox Code Playgroud)

如果需要,"请求/下载"可以执行一些安全检查,并生成文件传输:

$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);
  }

}
Run Code Online (Sandbox Code Playgroud)


joe*_*joe 9

我用隐藏的iframe完成了这个.我使用perl,而不是php,所以只提供概念,而不是代码解决方案.

客户端向服务器发送Ajax请求,导致生成文件内容.这将保存为服务器上的临时文件,并将文件名返回给客户端.

客户端(javascript)接收文件名,并将iframe src设置为将传递文件的某个URL,如:

$('iframe_dl').src="/app?download=1&filename=" + the_filename
Run Code Online (Sandbox Code Playgroud)

服务器篡改文件,取消链接,并使用这些标头将流发送到客户端:

Content-Type:'application/force-download'
Content-Disposition:'attachment; filename=the_filename'
Run Code Online (Sandbox Code Playgroud)

奇迹般有效.

  • “slurps”是一个技术术语吗? (2认同)

小智 6

不能直接通过ajax下载文件。

您可以在页面上放置一个链接,其中包含文件的 URL(从 ajax 调用返回),或者另一种方法是使用隐藏iframe并动态设置该源的 URL iframe。这样您就可以下载文件而无需刷新页面。

这是代码

$.ajax({
    url : "yourURL.php",
    type : "GET",
    success : function(data) {
        $("#iframeID").attr('src', 'downloadFileURL');
    }
});
Run Code Online (Sandbox Code Playgroud)