經過把Content-Type設置爲application/octet-stream,能夠把動態生成的內容看成文件來下載,相信這個你們都會。那麼用Content-Disposition設置下載的文件名,這個也有很多人知道吧。基本上,下載程序都是這麼寫的: php
<?php $filename = "document.txt"; header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . $filename); print "Hello!"; ?>
這樣用瀏覽器打開以後,就能夠下載document.txt。 html
可是,若是$filename是UTF-8編碼的,有些瀏覽器就沒法正常處理了。好比把上面那個程序稍稍改一下: 瀏覽器
<?php $filename = "中文 文件名.txt"; header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . $filename); print "Hello!"; ?>
把程序保存成UTF-8編碼再訪問,IE6下載的文件名就會亂碼。 FF3下下載的文件名就只有「中文」兩個字。Opera 9下一切正常。 服務器
輸出的header其實是這樣子: cookie
Content-Disposition: attachment; filename=中文 文件名.txt
其實按照RFC2231的定義,多語言編碼的Content-Disposition應該這麼定義: app
Content-Disposition: attachment; filename*="utf8''%E4%B8%AD%E6%96%87%20%E6%96%87%E4%BB%B6%E5%90%8D.txt"
即: ide
通過試驗,發現幾種主流瀏覽器的支持狀況以下: 函數
IE6 | attachment; filename="<URL編碼以後的UTF-8文件名>" |
FF3 | attachment; filename="UTF-8文件名" |
attachment; filename*="utf8''<URL編碼以後的UTF-8文件名>" | |
O9 | attachment; filename="UTF-8文件名" |
Safari3(Win) | 貌似不支持?上述方法都不行 |
這樣看來,程序必須得這樣寫才能支持全部主流瀏覽器: 編碼
<?php $ua = $_SERVER["HTTP_USER_AGENT"]; // $_SERVER["HTTP_USER_AGENT"]在IE中顯示爲: // Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko $filename = "中文 文件名.txt"; $encoded_filename = urlencode($filename); $encoded_filename = str_replace("+", "%20", $encoded_filename); header('Content-Type: application/octet-stream'); //if (preg_match("/MSIE/", $ua)) { //兼容IE11 if(preg_match("/MSIE/", $ua) || preg_match("/Trident\/7.0/", $ua)){ header('Content-Disposition: attachment; filename="' . $encoded_filename . '"'); } else if (preg_match("/Firefox/", $ua)) { header('Content-Disposition: attachment; filename*="utf8\'\'' . $filename . '"'); } else { header('Content-Disposition: attachment; filename="' . $filename . '"'); } print 'ABC'; ?>
備註:
ASCII:西歐字符集;
GB2312:國家簡體中文字符集,兼容ASCII;
BIG5:統一繁體字編碼;
GBK:它是GB2312的擴展,支持簡體和繁體字,兼容GB2312;
GB18030:在GBK基礎上繼續擴展生僻字和日文、朝鮮語等的編碼,兼容GBK;
UNICODE:爲世界650種語言進行統一編碼,只兼容ASCII對GB系列都不兼容。 url
另附:PHP實現下載功能超詳細流程分析
客戶端從服務端下載文件的流程分析:
注意:任何有關從服務器下載的文件操做,必然須要先在服務端將文件讀入內存當中
因此咱們須要在php代碼中設置一次讀取的字節數,好比我在下面的代碼中經過$buffer=1024設置一次讀取的字節數,每讀取一次,就輸出數據(即返回給瀏覽器)
流程圖:
代碼: <?php header("Content-type:text/html;charset=utf-8"); // $file_name="cookie.jpg"; $file_name="聖誕狂歡.jpg"; //用以解決中文不能顯示出來的問題 $file_name=iconv("utf-8","gb2312",$file_name); $file_sub_path=$_SERVER['DOCUMENT_ROOT']."marcofly/phpstudy/down/down/"; $file_path=$file_sub_path.$file_name; //首先要判斷給定的文件存在與否 if(!file_exists($file_path)){ echo "沒有該文件文件"; return ; } $fp=fopen($file_path,"r"); $file_size=filesize($file_path); //下載文件須要用到的頭 Header("Content-type: application/octet-stream"); Header("Accept-Ranges: bytes"); Header("Accept-Length:".$file_size); Header("Content-Disposition: attachment; filename=".$file_name); $buffer=1024; $file_count=0; //向瀏覽器返回數據 while(!feof($fp) && $file_count<$file_size){ $file_con=fread($fp,$buffer); $file_count+=$buffer; echo $file_con; } fclose($fp); ?>
幾點注意事項: