首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

解決 PHP 下載中文檔名亂碼的跨瀏覽器方案

     編輯:PHP 相關知識

問題背景

使用 Content-Disposition: attachment; filename=... 指定下載檔名時,若檔名包含中文(UTF-8),各瀏覽器處理方式不一:IE6 亂碼、Firefox 3 截斷、Opera 9 正常、Safari 3 不支援。需依 RFC 2231 與瀏覽器實際行為實作相容方案。

標準與瀏覽器差異

瀏覽器支援的 Header 格式
IE6filename="URL編碼後的UTF-8檔名"
Firefox 3filename="UTF-8檔名" 或 filename*="utf8''URL編碼後的UTF-8檔名"
Opera 9filename="UTF-8檔名"
Safari 3 (Win)上述皆不支援

RFC 2231 標準格式

Content-Disposition: attachment; filename*="utf8''%E4%B8%AD%E6%96%87%20%E6%96%87%E4%BB%B6%E5%90%8D.txt"
  • filename* 星號表示編碼版本
  • 值以單引號分三段:字元集(utf8)、語言(空)、URL 編碼後檔名
  • 雙引號包裹可避免 Firefox 中空格後內容截斷
  • 空格需編碼為 %20,而非 PHP urlencode() 的 +

跨瀏覽器相容實作

<?php
$ua = $_SERVER['HTTP_USER_AGENT'];
$filename = '中文 檔名.txt';
$encoded = str_replace('+', '%20', urlencode($filename));

header('Content-Type: application/octet-stream');

if (preg_match('/MSIE/', $ua)) {
    // IE: filename + URL 編碼
    header("Content-Disposition: attachment; filename=\"{$encoded}\"");
} elseif (preg_match('/Firefox/', $ua)) {
    // Firefox: RFC 2231 格式
    header("Content-Disposition: attachment; filename*=\"utf8''{$encoded}\"");
} else {
    // 其他: 直接 UTF-8
    header("Content-Disposition: attachment; filename=\"{$filename}\"");
}

echo 'File content...';
?>

進階建議

  • 現代專案可改用 Content-Disposition: attachment; filename*=UTF-8''... 單一格式,主流瀏覽器(Chrome、Firefox、Edge、Safari 10+)均已支援。
  • 若需支援舊版 Safari,可在伺服器端以英文/數字重新命名檔案,或提供 ZIP 打包下載繞過檔名編碼問題。
  • 務必對檔名進行嚴格過濾,防止路徑遍歷與 Header 注入攻擊。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved