用ajax和php下载文件

时间:2015-02-01 10:32:21

标签: php jquery ajax

在我的HTML中,我有

$('#vcc').click(function() { get_file() } );

function get_file()
{
    $.ajax({ url: "test.php",context: document.body})
    .done(function(text)
    {
    ....
    });
}

test.php我正在生成pdf文档。

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header("Content-Type: application/force-download");
    header('Content-Disposition: attachment; filename=' . urlencode(basename("factures/facture_2015_03.pdf")));
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . strlen($response));

    ob_clean();
    flush();
    echo $response;

如果我直接调用test.php,它正在运行,则会下载该文件。

现在我想让它使用ajax调用。但是我不知道在...我用document.write尝试了什么。 pdf文件的内容显示在我的浏览器中,但未下载。

我该怎么办?


编辑:

现在我的local.php包含

<html>

<head>
    <script type="text/javascript" src="js/jquery-2.1.3.min.js"></script>
    <script type="text/javascript">

    $( document ).ready(function() { document_ready(); } );

    function document_ready()
    {
        $('#vcc').click(function() { get_ajax() } );

        $.ajaxTransport("+binary", function(options, originalOptions, jqXHR)
        {
            // check for conditions and support for blob / arraybuffer response type
            if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))
            {
                return {
                        // create new XMLHttpRequest
                        send: function(_, callback){
                            // setup all variables
                            var xhr = new XMLHttpRequest(),
                                url = options.url,
                                type = options.type,
                                // blob or arraybuffer. Default is blob
                                dataType = options.responseType || "blob",
                                data = options.data || null;

                            xhr.addEventListener('load', function(){
                                var data = {};
                                data[options.dataType] = xhr.response;
                                // make callback and send data
                                callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
                            });

                            xhr.open(type, url, true);
                            xhr.responseType = dataType;
                            xhr.send(data);
                        },
                        abort: function(){
                            jqXHR.abort();
                        }
                    };
                }
            });
        }

        function get_ajax()
        {
            $.ajax({
                  url: "remote.php",
                  // data that you want send to PHP script
                  data: { fileId: "random", extraData: "some value" },
                  type: "GET", // or POST
                  dataType: "binary", // make our special transfer type
                  processData: false,
                  success: function(text)
                  {
                  var pdfContent = [text]; // change to Array
                  var fakeFile= new Blob(pdfContent, {type: 'application/pdf'});
                  SaveToDisk(fakeFile, "form1.pdf")
                  }
                });
        }

        function SaveToDisk(blobURL, fileName) {
            var reader = new FileReader();
            reader.readAsDataURL(blobURL);
            reader.onload = function (event) {
                var save = document.createElement('a');
                save.href = event.target.result;
                save.target = '_blank';
                save.download = fileName || 'unknown file';

                var event = document.createEvent('Event');
                event.initEvent('click', true, true);
                save.dispatchEvent(event);
                (window.URL || window.webkitURL).revokeObjectURL(save.href);
            };
        }

    </script>
</head>

<body>

<div>
    <input type="submit" id="vcc" value="Go"></input>
</div>

</body>

remote.php

<?php 

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . urlencode(basename("form1.pdf")));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');

$response = readfile("form1.pdf");

header('Content-Length:' . strlen($response));

ob_clean();
flush();

print  $response;

?>

结果

enter image description here

5 个答案:

答案 0 :(得分:2)

我不确定[我使用jQuery的其他解决方案在Firefox中不起作用..]。像许多其他人所说,你不应该使用AJAX / jQuery来制作网络浏览器下载文件。

示例:

page.htm 下载链接/按钮/任何内容:

<!doctype html>
<html>
<head>
    <title>Download fake file from JS script example</title>
    <meta charset="utf-8">
    <script>
function downloadPdfExample()
{
    // simple :)
    window.location = "download_pdf.php";
}
    </script>
</head>
<body>
Click on button below to start download:<br />
<button onclick="downloadPdfExample()">Start PDF download</button><br />

</body>
</html>

download_pdf.php 文件会强制浏览器下载文件,而不是显示在新卡/当前卡中:

<?php
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . urlencode(basename("form1.pdf")));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
readfile("example.pdf");

flush();

我对JS代码的想法过多,忘记了PHP。

正如您在PHP页面上的示例中所见(http://php.net/manual/en/function.readfile.php#example-2524 readfile(&#39; filename&#39;); 不会返回文件内容。它打印在&#39;输出&#39;!

所以..这部分代码:

$response = readfile("form1.pdf");
header('Content-Length:' . strlen($response));

引发错误!发送文件内容后,您无法设置响应标题 readfile 将文件内容发送到浏览器,而不是将其变为 $ response !)

$ response 中发送给浏览器的数据长度为,因此 strlen($ reponse)也不起作用。

答案 1 :(得分:1)

无法使用 JavaScript / JQuery 下载文件...因为他们无法在客户端创建文件 您可以输入一个链接来下载您的文件,而不是

<a href="test.php">Download file </a>

或者您可以使用纯 JavaScript 重定向

document.location.href = "test.php"

答案 2 :(得分:1)

您可以在新浏览器中创建文件(IE仅限10+,所有Chrome,Firefox,Safari ..)。

保存生成文件的代码:

function SaveToDisk(blobURL, fileName) {
    var reader = new FileReader();
    reader.readAsDataURL(blobURL);
    reader.onload = function (event) {
        var save = document.createElement('a');
        save.href = event.target.result;
        save.target = '_blank';
        save.download = fileName || 'unknown file';

        var event = document.createEvent('Event');
        event.initEvent('click', true, true);
        save.dispatchEvent(event);
        (window.URL || window.webkitURL).revokeObjectURL(save.href);
    };
}

生成文件的代码:

var pdfContent = ['file content']; // create Array bytes of file or with it's content as string
var fakeFile= new Blob(pdfContent, {type: 'application/pdf'});

强制浏览器将其保存在光盘上:

SaveToDisk(fakeFile, "my.pdf")

修改

PDF文件 - 和许多其他人一样 - 都是二进制文件&#39;在JS中不是默认的格式,但是jQuery让我们制作了插件&#39;添加这样的新功能(传输二进制文件,完整教程:http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/

在jQuery加载之后将其添加到某个位置&#39;和AJAX之前的&#39;:

$.ajaxTransport("+binary", function(options, originalOptions, jqXHR){
    // check for conditions and support for blob / arraybuffer response type
    if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))
    {
        return {
            // create new XMLHttpRequest
            send: function(_, callback){
                // setup all variables
                var xhr = new XMLHttpRequest(),
                    url = options.url,
                    type = options.type,
                    // blob or arraybuffer. Default is blob
                    dataType = options.responseType || "blob",
                    data = options.data || null;

                xhr.addEventListener('load', function(){
                    var data = {};
                    data[options.dataType] = xhr.response;
                    // make callback and send data
                    callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
                });

                xhr.open(type, url, true);
                xhr.responseType = dataType;
                xhr.send(data);
            },
            abort: function(){
                jqXHR.abort();
            }
        };
    }
});

ajax 调用应该是这样的[记得从上面的代码中添加函数 SaveToDisc ]:

$.ajax({
  url: "generate/pdf/test.php",
  // data that you want send to PHP script
  data: { fileId: "random", extraData: "some value" },
  type: "GET", // or POST
  dataType: "binary", // make our special transfer type
  processData: false,
  success: function(text){
  var pdfContent = [text]; // change to Array
  var fakeFile= new Blob(pdfContent, {type: 'application/pdf'});
  SaveToDisk(fakeFile, "myPdfDownloader.pdf")
  }
});

我再次进行了测试,它对我有用。我希望你现在可以接受我的答案:)

答案 3 :(得分:0)

我假设您在单击链接或文本div来下载文档时,您不希望将页面定向到该php文件,输入,您希望它在同一页面中而不通过JQUERY路由另一页你需要在jquery中调用ajax方法。 确保你包含了更正和更新的JQuery库。然后假设您希望通过ajax下载名为“ozan”的文档。然后我假设它的文本是“ozan”然后在jquery中你可以把它写成:

$(document).ready(function(){
$("#document_name").click(function(){
var documentname=$(this).val();
$.ajax({method:"POST",
url:"test.php",
data:{name:documentname},
success:function(incoming){`
alert("Downloading...");
}
});});

当您创建ajax时,它将在test.php中自动发送文档名称而不刷新页面,然后在该php中获取值:

if(isset($_POST["name"])){
$document_name=$_POST["name"];
}
  

然后你可以在这个php文件

中的代码片段下面写下载代码

答案 4 :(得分:0)

您可以设置一个包含下载属性的下载按钮:

http://www.w3schools.com/tags/att_a_download.asp