2011-07-12 151 views
29

我有一個按鈕和onclick它會調用ajax函數。通過ajax調用下載文件php

這裏是我的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); 
} 

我創建一個基於用戶輸入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"; 

但如果我在csv.php結束時運行它,它的FILE.CSV的內容輸出到頁面中(到ajaxDiv),而不是下載。

有沒有辦法強制下載文件在csv.php結束?

回答

36

AJAX不適用於下載文件。以下載鏈接作爲地址彈出一個新窗口,或執行document.location = ...

+16

我認爲在技術上是最好設置'window.location';看到這個討論:http://stackoverflow.com/questions/7857878/window-location-vs-document-location – yitwail

8

我已經用隱藏的iframe實現了這一點。我使用Perl,而不是PHP,所以只會給概念,而不是代碼解決方案。

客戶端向服務器發送Ajax請求,導致生成文件內容。這將作爲臨時文件保存在服務器上,並將文件名返回給客戶端。

客戶端(JavaScript)的接收文件名,並設置IFRAME SRC的一些網址,將提供的文件,如:

$('iframe_dl').src="/app?download=1&filename=" + the_filename 

服務器吸食文件,解除鏈接它,流發送給客戶端,與這些標頭:

Content-Type:'application/force-download' 
Content-Disposition:'attachment; filename=the_filename' 

工程就像一個魅力。

8

@joe:非常感謝,這是一個好頭!

我有一個稍微難一點的問題:1。 與發送POST數據的AJAX請求,服務器產生一個ZIP文件 2.得到一個響應返回 3.下載ZIP文件

所以這是我是如何做到的(使用jQuery處理Ajax請求):

  1. 初始POST請求:

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

「request/url」處理壓縮文件的創建(關閉主題,所以我不會發布完整的代碼)並返回以下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; 

「請求/下載」 可以執行某些安全檢查,如果需要的話,並生成文件傳輸:採用

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

} 
+0

只是&需要改變到?爲查詢字符串。感謝這個雖然真棒幫助! - 我試圖做一個編輯,但它是如此之小,它不會讓我! $ dlink ='http://'.$_SERVER [「SERVER_NAME」]。'/ request/download?file ='。$ zipid; –

19

一個非常簡單的解決方案的jQuery:

上客戶端:

$('.act_download_statement').click(function(e){ 
    e.preventDefault(); 
    form = $('#my_form'); 
    form.submit(); 
}); 

並在服務器端,請確保您發回正確Content-Type標題,所以瀏覽器將知道它的附件,下載將開始。

+1

+1這對我來說很適合將數據發佈到服務器並獲取ZIP文件下載作爲響應。沒有頁面重新加載。 –

+0

+1這篇文章更技術化,是一個很好的訣竅 – bizzr3

+0

你可以提供更多的細節,並提供一些關於兩端發生的事情的代碼嗎? –

2

您無法通過ajax直接下載文件。

您可以在頁面上放置一個帶有您的文件的URL(從ajax調用返回)的鏈接,或者另一種方式是使用隱藏的iframe並動態設置iframe的源的URL。這樣您就可以在不刷新頁面的情況下下載文件。

下面是代碼

$.ajax({ 
    url : "yourURL.php", 
    type : "GET", 
    success : function(data) { 
     $("#iframeID").attr('src', 'downloadFileURL'); 
    } 
}); 
+0

發佈相關代碼將有助於說明您想要在此說的內容。 – larsAnders

+0

對你的ajax成功響應你可以設置隱藏的iframe src –