今天碰到文件下載的一些問題,本着知其然也要知其因此然的精神,站在巨人的肩膀上深刻學習和測試了一下,拋磚引玉,如今總結結論以下:javascript
1)標準URL下載方式
能夠經過在web頁面中嵌入 url超級連接,標準的HTTP GET請求,形如:「http://www.wjj.cc/test.zip」 的方式來下載。對於服務器端web根目錄有一個test.zip的文件。不解釋了,傻子都明白,看不明白就也沒有必要去搞IT了。
說明:此種方法的弊端是徹底暴露了文件test.zip的網站路徑,並且動態性不夠靈活。網上已經不少資料,很少說了。php
2)經過服務器端腳本向瀏覽器方(stdout)輸出二進制流的方式下載。好比 html頁面中嵌入URL爲:http://www.wjj.cc/download.php&f=test.zip ,此方法是GET方式請求,URL徹底能夠獲取到。
說明:上述方法能夠在服務器端 經過 腳本程序 download.php ,而且根據傳入的查詢字符串f=test.zip定位服務器上文件系統test.zip的路徑,而後按二進制流的方式發送給客戶端瀏覽器,那麼客戶端瀏覽器就會彈出一個「下載對話框」了。
另外一種方式是經過 提交表單,用POST方式提交參數到服務器端動態腳本,而後服務器端腳本返回輸出的二進制流到瀏覽器實現下載。尤爲是當須要下載的文件(可能不必定是服務器上文件系統中具體的文件,有多是服務器動態生成的數據) 依賴於客戶端提交的不少參數選項的時候,採用POST下載的方式是最多的。html
下面重點講述經過動態腳本實現下載的一些例子,下面的例子中均沒有給出服務器端動態腳本的處理代碼:java
1. GET URL下載連接,能夠直接嵌入到 <a href="URL...">下載</a> 。
2. POST的URL下載連接,能夠經過設置<form>表單的action 以及 表單元素值來完成下載。
3. 若是是GET方式的url下載連接,客戶端能夠經過一個動態生成的隱藏的iframe來獲得下載的二進制文件。原理是:iframe有一個src屬性,其本質就是發送http請求,GET一個頁面或者數據。javascript以下:
function download(){
var IFrameRequest=document.createElement("iframe");
IFrameRequest.id="IFrameRequest";
IFrameRequest.src="/test.zip";
IFrameRequest.style.display="none";
document.body.appendChild(IFrameRequest);
}web
4. 用動態生成的form元素,實現表單提交,開完成下載。注意:此方法不是ajax哦。
參考url:http://www.cnblogs.com/sydeveloper/archive/2013/05/14/3078295.html
要說明的是,這裏的原理僅僅是form提交表單,而不是ajax。ajax
因爲jQuery的ajax函數、及ajaxSubmit等函數的返回類型(dataType)只有xml、text、json、html等類型,沒有「流」類型,故咱們要實現ajax下載時,不可以使用相應的ajax函數進行文件下載。json
在網上看了一些文章,發現能夠經過js生成一個form,用這個form提交參數,並返回「流」類型的數據。在實現過程當中,頁面也沒有進行刷新。數組
請看實例:瀏覽器
var form = $("<form>"); //定義一個form表單服務器
form.attr('style','display:none'); //下面爲在form表單中添加查詢參數
form.attr('target','');
form.attr('method','post');
form.attr('action',"exportSms");
var input1 = $('<input>');
input1.attr('type','hidden');
input1.attr('name','exportPostTime');
input1.attr('value',timeString);
$('body').append(form); //將表單放置在web中
form.append(input1); //將查詢參數控件提交到表單上
form.submit(); //表單提交
5. 我在Asterisk中實現批量下載錄音的js代碼和php代碼
javascript代碼以下:
//批量下載錄音
function batchDownloadRecording(){
var rows = $('#taskRecords_search').datagrid('getSelections');
var form = $("<form>");
form.attr('style','display:none');
form.attr('target','');
form.attr('method','post');
form.attr('action',"index.php?m=SystemReport&a=batchDownloadRecording");
$('body').append(form);
//構建表單
var rows = $('#taskRecords_search').datagrid('getSelections');
for (var i = 0; i < rows.length; i++){
var input = $('<input>');
input.attr('type','checkbox');
//input.attr('name','selectlist');
input.attr('name','selectlist[]'); //很是重要,這裏必須加上[],由於是checkbox表單數組
input.attr('value',rows[i].userfield);
//alert(rows[i].userfield);
input.attr('checked',true);//很是重要,這裏必定要選中,不然服務器端收到的是空數組
form.append(input);
}
form.submit();
}
web服務器端php代碼以下: //批量下載錄音 function batchDownloadRecording(){ $arrUF = $_POST['selectlist']; //dump($arrUF);die; $monitorDir = '/var/spool/asterisk/monitor'; header('HTTP/1.1 200 OK'); header('Date: ' . date("D M j G:i:s T Y")); header('Last-Modified: ' . date("D M j G:i:s T Y")); header("Content-Type: application/force-download"); header("Content-Transfer-Encoding: Binary"); header("Content-Disposition: attachment;filename=Recording-" .Date('Ymd-His') .".tar.gz"); $cmd = "cd $monitorDir;tar -zcf - "; foreach($arrUF AS $uf){ $arr = explode("_",$uf); $arr = explode(".",$arr[2]); $timestamp = $arr[0]; //要轉化成mp3文件 $wavFile = Date('Y-m',$timestamp) ."/" .Date('d',$timestamp) ."/" .str_replace(".wav",".mp3",$uf); //echo $wavFile;die; if(file_exists($monitorDir ."/" .$wavFile)){ $cmd .= $wavFile ." "; } } //echo $cmd;die; system($cmd); }