从Ajax调用时,文件下载脚本不起作用

时间:2012-01-07 16:51:51

标签: php ajax download

我使用以下脚本启动文件下载:

if (file_exists($newfilename)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($newfilename));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($newfilename));
    ob_clean();
    flush();
    readfile($newfilename);
    exit;
}

当我直接打开页面时它工作正常,但问题是,我需要从另一个页面通过Ajax调用此脚本。当我这样做,然后下载没有开始。脚本的其余部分完成了它应该做的事情。

我认为问题是无法以这种方式使用标题功能,但肯定有一种方法可以使其工作吗?

如果有任何帮助,这是Ajax功能:

<script type="text/javascript">
    // function create GetXmlHttpObject
    function GetXmlHttpObject()
    {
    if (window.XMLHttpRequest)
    {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    return new XMLHttpRequest();
    }
    if (window.ActiveXObject)
    {
    // code for IE6, IE5
    return new ActiveXObject("Microsoft.XMLHTTP");
    }
    return null;
    }

    function submitVideoAjax(){
    var myAjaxPostrequest=new GetXmlHttpObject();

    var t2_title=document.video_form.title.value;

    var parameters="title="+t2_title;

    myAjaxPostrequest.open("POST", "newdownloadmanager.php", true);
    myAjaxPostrequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    myAjaxPostrequest.send(parameters);
    myAjaxPostrequest.onreadystatechange=function(){
    if(myAjaxPostrequest.readyState==4){
    if(myAjaxPostrequest.status==200){
    document.getElementById("result").innerHTML=myAjaxPostrequest.responseText;
    document.getElementById("video_form").style.display = "none";

    }
    else    {
    document.getElementById("video_form").innerHTML="An error has occured making the request";
    }
    }
    }
    }
    </script>

这就是形式:

<form name='video_form' id='video_form' method="post">
<input type="hidden" name="title" id="title" value="Madelyn2-01.mp4"/>
<button type="button" name="submit_video" id="submit_video" onclick="submitVideoAjax();">Download</button>
</form>

5 个答案:

答案 0 :(得分:8)

您无法使用AJAX下载文件。这没有意义。您可以发送AJAX请求并在客户端上的成功处理程序中获取文件内容,但出于明显的安全原因,您无法对其进行太多操作。您无法将其保存在客户端计算机上,并且没有javascript API允许您提示用户将其保存在何处。

所以要下载文件,请不要使用AJAX。创建一个指向服务器端脚本的锚点,该脚本提供要下载的文件。

答案 1 :(得分:1)

可以使用AJAX下载文件。

<强>的javascript

function exportToCsv(){

    var xmlhttp;

    if(window.XMLHttpRequest){ xmlhttp = new XMLHttpRequest; }else{ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
    xmlhttp.onreadystatechange = function(){
        if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
                window.location="download.php?filename=export.csv";
            }

        }
    }
    request = "exportToCsv.php";
    xmlhttp.open("GET", request, true);
    xmlhttp.send();

}

上面的代码,将联系人的mysql数据库导出到.csv文件。之后,如果一切正常,(xmlhttp.readyState == 4)会自动开始下载。 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

答案 2 :(得分:0)

javascript无法下载文件作为安全问题。

答案 3 :(得分:0)

AJAX请求与其他浏览器HTTP请求不同。您只需要使用about="_blank"或类似的东西为您的脚本添加所需参数的链接。现代浏览器很好用。

答案 4 :(得分:0)

当我需要使用ajax下载文件时,我遇到以下两种情况之一:

  • 要下载的文件扩展名可由网络服务器解释(html,txt,pl,php),具体取决于服务器的配置方式
  • 文件的扩展名是另一个,它存在于URL中映射的物理(或逻辑)文件。

在第二种情况下,在ajax答案中编写元标记就足够了,将其写入任何元素的innerHTML:

<meta http-equiv = "refresh" content="0;URL='somedir/worksheet.xls'" />

由于xls扩展指向现有文件,因此将立即提供给用户下载。

然而,在第一种情况下,不可能使用元标记,因为扩展名是html或网络服务器可以解释的任何其他扩展,并将被重定向到我们的网站。

由于通常的做法是提供一个锚点,其中包含要为不自动开始下载的情况下载的文件的URL,我应用此解决方案:首先,我编写了hiperlink

<p> If the download does not start, 
  <a id="link_id" href='somedir/some.html'> click here</a> 
</p>

进入页面的某个元素,然后单击锚元素

使回调函数
document.getElementById ("link_id").click();