简体   繁体   English

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

[英]File download script doesn't work when called from Ajax

I'm using the following script to initiate file downloads: 我正在使用以下脚本来启动文件下载:

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

It works fine when I open the page directly, but the thing is, I need this script to be called through Ajax from another page. 当我直接打开页面时,它工作正常,但问题是,我需要从另一个页面通过Ajax调用此脚本。 When I do that, then the download doesn't start. 当我这样做,然后下载没有开始。 The rest of the script does what it's supposed to. 脚本的其余部分完成了它应该做的事情。

I assume the problem is not being able to use the header function this way, but surely there's a way to make this work? 我认为问题是无法以这种方式使用头功能,但肯定有办法让这个工作吗?

This is the Ajax function if it's of any help: 如果它有任何帮助,这是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>

And this is the form: 这是形式:

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

You cannot use AJAX to download files. 您无法使用AJAX下载文件。 It doesn't make sense. 这没有意义。 You can send the AJAX request and fetch the file contents inside the success handler on the client, but for obvious security reasons you can't do much with it. 您可以发送AJAX请求并在客户端上的成功处理程序中获取文件内容,但出于明显的安全原因,您无法对其进行太多操作。 You cannot save it on the client computer and there's no javascript API allowing you to prompt the user where to save it. 您无法将其保存在客户端计算机上,并且没有javascript API允许您提示用户将其保存在何处。

So to download files, don't use AJAX. 所以要下载文件,不要使用AJAX。 Create an anchor pointing to your server side script that serves the file to be downloaded. 创建一个指向服务器端脚本的锚点,该脚本提供要下载的文件。

It is possible to download a file using AJAX. 可以使用AJAX下载文件。

javascript : 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();

}

The code above, exports a mysql database of contacts to a .csv file. 上面的代码,将联系人的mysql数据库导出到.csv文件。 After that, if everything is Ok (xmlhttp.readyState == 4) automatically starts the download. 之后,如果一切正常(xmlhttp.readyState == 4)自动开始下载。 window.location="download.php?filename=export.csv";

download.php file : 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);

?>

After this, the browser just presents the "Save file as" dialog, and no page refresh happens whatsoever. 在此之后,浏览器只显示“将文件另存为”对话框,并且不会发生任何页面刷新。 I have the application up and running, and never had problems. 我有应用程序启动并运行,从来没有遇到过问题。 Runs on the following browsers: 在以下浏览器上运行:

Chrome v37.0.2062.120 
Firefox v32.0.1
Opera v12.17
Internet Explorer v11

When I need to download a file using ajax, I have one of the following two situations: 当我需要使用ajax下载文件时,我有以下两种情况之一:

  • The extension of the file to download is interpretable by the webserver (html, txt, pl, php), depending on how the server is configured 要下载的文件的扩展名可由Web服务器(html,txt,pl,php)解释,具体取决于服务器的配置方式
  • The extension of the file is another, and it exists the physical (or logical) file mapped in the URL. 文件的扩展名是另一个,它存在于URL中映射的物理(或逻辑)文件。

In this second case, it is enough to write a meta tag in the ajax answer, writing it into any element's innerHTML: 在第二种情况下,在ajax答案中编写元标记就足够了,将其写入任何元素的innerHTML:

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

Since the xls extension points to an existing file it will be immediately offered to the user for download. 由于xls扩展指向现有文件,因此将立即提供给用户进行下载。

In the first case, however, it is not possible to use the meta tag, since the extension is html or any other interpretable by the webserver and will be served redirecting our website. 然而,在第一种情况下,不可能使用元标记,因为扩展名是html或网络服务器可解释的任何其他扩展,并将被重定向到我们的网站。

As it is usual practice to offer an anchor with the URL of the file to be downloaded for the case that does not start the download automatically, I apply this solution: first, I write the hiperlink 由于通常的做法是提供一个锚点,其中包含要自动下载的文件的URL,而不是自动开始下载,我应用此解决方案:首先,我编写hiperlink

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

into some element of the page and then make the callback function click on the anchor element 进入页面的某个元素然后使回调函数单击锚元素

document.getElementById ("link_id").click();

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

AJAX requests does not served the same that other browser HTTP request do. AJAX请求与其他浏览器HTTP请求的作用不同。 You need only to put a link to your script with desired parameters, using about="_blank" or something like this. 您只需要使用about="_blank"或类似的东西为您的脚本添加所需参数的链接。 Modern browsers serve that well. 现代浏览器很好用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM