[英]Download CSV file using “AJAX”
我正在嘗試為我的網站完成一個相當簡單的任務,但我不確定如何去做。我希望用戶查看一個表,然后單擊一個按鈕,此時用戶可以保存該表的內容為csv文件。此請求有時可能非常復雜,因此我生成一個進度頁面以提醒用戶。
除了實際生成csv文件之外,我發現了大多數事情。 (我使用jQuery和PHP)
點擊運行jQuery代碼:
hmis_query_csv_export: function(query_name) {
$.uiLock('<p>Query Loading.</p><img src="/images/loading.gif" />')
$.get({
url: '/php_scripts/utils/csv_export.php',
data: {query_name: query_name},
success: function(data) {
$.uiUnlock();
}
});}
相關的PHP:
header("Content-type: text/x-csv");
header("Content-Disposition: attachment; filename=search_results.csv");
//
//Generate csv
//
echo $csvOutput
exit();
這樣做是將文本作為PHP文件發送,但它不會生成下載。 我究竟做錯了什么?
如果要強制下載,可以將當前頁面重定向到下載鏈接。 由於鏈接將生成下載對話框,因此當前頁面(及其狀態)將保留在原位。
基本方法:
$('a#query_name').click(function(){
$('#wait-animation').show();
document.location.href = '/php_scripts/utils/csv_export.php?query_name='+query_name;
$('#wait-animation').hide();
});
更復雜:
$('a#query_name').click(function(){
MyTimestamp = new Date().getTime(); // Meant to be global var
$('#wait-animation').show();
$.get('/php_scripts/utils/csv_export.php','timestamp='+MyTimestamp+'&query_name='query_name,function(){
document.location.href = '/php_scripts/utils/csv_export.php?timestamp='+MyTimestamp+'&query_name='+query_name;
$('#wait-animation').hide();
});
});
在PHP腳本:
@header("Last-Modified: " . @gmdate("D, d M Y H:i:s",$_GET['timestamp']) . " GMT");
@header("Content-type: text/x-csv");
// If the file is NOT requested via AJAX, force-download
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
header("Content-Disposition: attachment; filename=search_results.csv");
}
//
//Generate csv
//
echo $csvOutput
exit();
兩個請求的URL必須相同才能欺騙瀏覽器不要在document.location.href
開始新的下載,而是將副本保存在緩存中。 我不是很確定,但看起來很有希望。
編輯我剛嘗試使用10MB文件,似乎val()太慢,無法插入數據。 Hurrumph。
好的,所以我給了另一個去。 這可能是也可能不是完全瘋了! 我們的想法是創建一個AJAX請求來創建數據,然后使用回調將數據插入到當前頁面上的隱藏表單中,該頁面具有第三個“下載”頁面的操作; 插入后,表單自動提交,下載頁面發送標題並回顯POST,等等,下載。
一直以來,在原始頁面上,您已經指示文件正在准備中,並且在完成時指示符已更新。
注意:此測試代碼未經過廣泛測試,並且沒有真正的安全檢查(或根本沒有)。 我用1.5MB的CSV文件對它進行了測試,這個文件非常合理。
的index.html
<a id="downloadlink" href="#">Click Me</a>
<div id="wait"></div>
<form id="hiddenform" method="POST" action="download.php">
<input type="hidden" id="filedata" name="data" value="">
</form>
test.js
$(document).ready(function(){
$("#downloadlink").click(function(){ // click the link to download
lock(); // start indicator
$.get("create.php",function(filedata){ // AJAX call returns with CSV file data
$("#filedata").val(filedata); // insert into the hidden form
unlock(); // update indicator
$("#hiddenform").submit(); // submit the form data to the download page
});
});
function lock(){
$("#wait").text("Creating File...");
}
function unlock(){
$("#wait").text("Done");
}
});
create.php
<?php
//create $data
print $data;
?>
的download.php
<?php
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: text/x-csv");
header("Content-Disposition: attachment;filename=\"search_results.csv\"");
if($_POST['data']){
print $_POST['data'];
}
?>
完成此任務的最佳方法是使用數據URI,如下所示:
請參閱此鏈接以獲取相關說明(特別是第3段): http : //en.wikipedia.org/wiki/Data_URI_scheme
這樣,您不需要在服務器上保存任何文件,也不需要使用iframe或隱藏的表單元素或任何此類黑客。
我認為您不能使用AJAX / JS請求進行瀏覽器下載。 嘗試使用導航到生成CSV的頁面的隱藏iframe
那么使用AJAX的目的是避免頁面的可見重載。 如果您想要下載,則需要相反的 - 來自瀏覽器的全新請求。 我會說,只需創建一個指向您的php頁面的簡單按鈕。
為了回應和擴展其他人所說的內容,你無法使用AJAX真正發送文件。 造成這種情況的原因之一是(有人糾正我,如果我錯了,請)您當前所在的頁面已經發送了其內容標題; 你不能再將它們發送到同一個窗口,即使有一個AJAX請求(這是你的PHP文件試圖做的)。
我之前在項目中所做的是簡單地提供一個鏈接(帶有target =“_ blank”或javascript重定向)到一個單獨的下載PHP頁面。 如果您正在使用Apache,請查看mod_xsendfile。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.