核心代碼片段
<?php
if (isset($link)) {
header("HTTP/1.1 303 See Other");
header("Location: $link");
exit;
}
?>
國外專家建議的優化寫法
<?php
// 處理表單...
// 重定向到結果頁
header('Status: 303 See Other');
header('Location: https://www.example.com/result.html');
// 不要在這之後有任何輸出
?>
關鍵差異解析
| 項目 | 常見寫法 | 推薦寫法 | 理由 |
| 狀態行 | header("HTTP/1.1 303 See Other") | header('Status: 303 See Other') | Apache 產生的回應頭更標準,避免猜測 HTTP 版本 |
| Location 值 | 相對路徑 result.html | 完整 URI https://example.com/result.html | RFC 規定 Location 必須為完整 URI |
| 後續輸出 | 可能有 exit('...') 帶字符串 | 無任何輸出 | 重定向後不應輸出內容,避免客戶端解析異常 |
完整下載腳本範例
<?php
// download.php
$fileId = $_GET['id'] ?? '';
if (!$fileId) { http_response_code(400); exit('缺少參數'); }
// 業務邏輯:驗證權限、記錄日誌、生成簽名 URL 等...
$downloadUrl = generateSignedUrl($fileId); // 假設函數
// 發送 303 重定向
header('Status: 303 See Other');
header("Location: $downloadUrl");
// 關鍵:立即結束腳本,防止後續輸出干擾
exit;
?>
適用場景
- 表單提交後避免重複提交(PRG 模式)
- 大文件下載前驗證權限,再導向 CDN/對象存儲簽名 URL
- API 回調、OAuth 授權碼流程重定向
常見坑點提醒
- 輸出緩衝:若開啟了
ob_start(),重定向前需 ob_end_clean() 或確保無輸出。
- Header 已發送:任何
echo、空白行、BOM 都會導致「headers already sent」錯誤。
- 相對路徑:某些舊版瀏覽器/爬蟲對相對 Location 支援不佳,統一用絕對 URL。