【问题标题】:File download script doesn't work when called from Ajax从 Ajax 调用时文件下载脚本不起作用
【发布时间】:2012-02-04 23:30:52
【问题描述】:

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

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>

【问题讨论】:

  • 是什么让您相信它可以工作?因为你想要它?

标签: php ajax download


【解决方案1】:

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

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

【讨论】:

  • 对,好吧,这很有道理。我想我只需将脚本包含在同一页面上并自行提交即可。
  • 如果我们希望只允许经过身份验证的用户下载文件怎么办?那么问题是,如何从浏览器执行 GET 请求,并适当修改标头(以便可以在服务器端对事务进行身份验证),并且只有在身份验证成功后,服务器才会以文件响应。有什么建议?我来自这里:stackoverflow.com/q/28056246/1355058
  • 您找到解决方案了吗?我面临同样的问题。我可以在 ajax 成功中获取文件内容。但不知道下一步该做什么。有没有其他方法可以用ajax下载文件?
【解决方案2】:

由于安全问题,javascript 无法下载文件。

【讨论】:

    【解决方案3】:

    AJAX 请求的服务方式与其他浏览器 HTTP 请求不同。您只需要使用about="_blank" 或类似的东西将一个链接放到带有所需参数的脚本。现代浏览器可以很好地满足这一点。

    【讨论】:

      【解决方案4】:

      可以使用 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";

      下载.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
      

      【讨论】:

      • 这颠覆了我对 AJAX 的了解。感谢您的时间和麻烦。
      【解决方案5】:

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

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

      在第二种情况下,在ajax答案中写一个meta标签就足够了,写到任何元素的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();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多