iT邦幫忙

0

PHP強迫下載問題

php

客戶的網站為多國語系
所以在後台上傳檔案時,都將其檔案更改檔名為數字
但客戶希望下載時可以還原本來的檔名
所以我用了語法讓下載該檔案時可以結合他原本的檔名
但經過測試,除了英文以外的語系
在IE使用時檔名會變成亂碼,Firefox、Chrome、Opera、Safari都沒問題
想說是不是IE先天條件就不行存取非英文檔名,但我在Server設一個直接連結中文檔名的超連結
IE又可以正確的下載中文檔名檔案
不知道是否可以在PHP端這邊透過宣告使IE可以正常下載

<?php
if (isset($_GET['download'])) {
	$source = 'test.rar';
	$name = '測試';
	header("Content-Type: application/octet-stream");
	header("Content-Disposition: attachment; filename=$name.rar");
	readfile($source);
	exit;
}
?>

<html xmlns="http://www.w3.org/1999/xhtml">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>download</title>



<a href="測試.rar">test</a><br />
<a href="test.php?download=1" target="_blank"">download</a>
ycl8000 iT邦高手 1 級 ‧ 2010-07-18 08:46:49 檢舉
提供一個方向,多年前在架設phpBB時,也遇到這個問題,後來在竹貓星球上找到解決方案,怎麼解不太記得了,你可以去那邊找看看。

2 個回答

6
fillano
iT邦超人 1 級 ‧ 2010-07-17 09:01:12
最佳解答

用urlencode把檔名編碼就可以了。但是這要對IE(透過$_SERVER["HTTP_USER_AGENT"]來找特徵字串)做特別處理,其他瀏覽器不會把urlencode過的檔名解回來。另外一個要讓IE正確辨識檔名的條件是他必須是網頁中的連結,檔名編碼與網頁編碼一致,像你的程式一樣,所以應該沒問題。

http://en.wikipedia.org/wiki/MIME 裡面有解釋Content-Disposition Header,用他當索引來看標準文件會比較清楚...

MUA應該會比較嚴格遵守標準...但是瀏覽器...看起來沒一家是遵守的,哈哈,而且處理方法不同。其實早期的MIME有嚴格規定Content-Disposition不可以用NON-ASCII,後來的標準則定義了在這些parameter field value裡面使用NON-ASCII的方法,不過不論IE或是其他家瀏覽器都不是遵守這個方法的樣子,而且方法不同,IE要用urlencode,其他家則直接支援NON-ASCII...

有空再來試試用RFC2231建議的方式來編碼檔名,各家瀏覽器可不可以支援。

看更多先前的回應...收起先前的回應...
fillano iT邦超人 1 級 ‧ 2010-07-19 16:07:41 檢舉

稍微測試過,結論如下:

IE只支援用urlencode的檔名。
Firefox 支援所有的方式。
Chrome / Safari 支援 RFC2047 定義的encoded word編碼方式。(我只測試了Chrome,不過Safari應該差不多)
Opera 支援 RFC2231 定義的方式

fillano iT邦超人 1 級 ‧ 2010-07-19 16:18:23 檢舉

用RFC2047或RFC2231的方式有一個好處,就是裡面會指定檔名的charset,所以理論上檔名跟link網頁的編碼不一樣,也沒問題(Firefox OK,其他就沒仔細測了)。

fillano iT邦超人 1 級 ‧ 2010-07-19 16:32:20 檢舉

如果有在用thunderbird,他可以用原始內容的格式來瀏覽郵件,這樣收到有附件的郵件時,就可以觀察一下裡面的Content-Disposition怎麼指定。看到長得像:

<pre class="c" name="code">filename="=?big5?B?UEVFc...

就是RFC2047定義的編碼方式,看到長得像:

<pre class="c" name="code">filename*0*=UTF-8''%E5%BD...
filename*1*=%E8%B3...

等就是RFC2231定義的編碼方式。

RFC2047中,charset後面那個欄位是內容編碼的方法,通常會用的有base64(B)及quoted printable(Q)。

RFC2231的話,charset後面還可以指定語言(在那個UTF-8之後的兩個單引號中間),例如en。

chan15 iT邦新手 5 級 ‧ 2010-07-21 12:42:12 檢舉

fillano大哥,code我這樣下ok嗎?

<pre class="c" name="code">if (isset($_GET['lan'])) {
	$source = 'test.rar';
	$nameArr = array('tw'=>'測試', 'jp'=>'テスト', 'ch'=>'测试', 'en'=>'test');
	$ie = 'MSIE';
	$compare = $_SERVER['HTTP_USER_AGENT'];
	$filename = stristr($compare, $ie) ? urlencode($nameArr[$_GET['lan']]) : $nameArr[$_GET['lan']];
	header("Content-Type: application/octet-stream");
	header("Content-Disposition: attachment; filename=$filename.rar");
	readfile($source);
	exit;
}
fillano iT邦超人 1 級 ‧ 2010-07-21 14:07:43 檢舉

應該是可以,不過還是建議您用不同瀏覽器測試一下。

6
shunyuan
iT邦研究生 1 級 ‧ 2010-07-16 21:24:22

你的 IE web page default ecode 是 UTF8 嗎?

chan15 iT邦新手 5 級 ‧ 2010-07-16 22:42:02 檢舉

你說網頁的編碼嗎?如果是的話是UTF-8沒錯。

shunyuan iT邦研究生 1 級 ‧ 2010-07-17 02:14:16 檢舉

chan15提到:
你說網頁的編碼嗎?如果是的話是UTF-8沒錯。

我指的是 Browser,有沒有可能 IE 不是用 UTF8 來解碼你的中文檔名(default 是設 big-5),因為你是用程式傳名字,據我所知,其他的瀏覽器,內定是 UTF8

我要發表回答

立即登入回答