使用 CodeIgniter 框架時,常遇到「Disallowed Key Characters」錯誤導致頁面空白。本文深入分析錯誤成因,提供修改核心檔案與配置調整兩種解決方案,並說明為何清除 Cookie 可暫時緩解問題。
CI 的 Input 類別在 _clean_input_keys() 方法中,使用正則 /^[a-z0-9:_/-]+$/i 驗證所有輸入鍵名(包括 $_GET、$_POST、$_COOKIE 的鍵)。當鍵名包含正則未涵蓋的字元(如中文、特殊符號、某些編碼字元)時,即拋出此錯誤並終止執行。
常見觸發情境:
編輯 system/core/Input.php,找到 _clean_input_keys() 方法並替換為:
function _clean_input_keys($str)
{
$config =& get_config('config');
// 使用設定檔中的 permitted_uri_chars,並對輸入進行 rawurlencode 後再比對
if ( ! preg_match("/^[" . $config['permitted_uri_chars'] . "]+$/i", rawurlencode($str)))
{
exit('Disallowed Key Characters.');
}
// Clean UTF-8 if supported
if (UTF8_ENABLED === TRUE)
{
$str = $this->uni->clean_string($str);
}
return $str;
}
原理: 原版直接比對原始字串,新版先 rawurlencode() 再比對,可通過百分號編碼後的字元(如 %E4%B8%AD%E6%96%87),只要 permitted_uri_chars 包含 % 即可通過。
config.php(推薦,不動核心)打開 application/config/config.php,找到 $config['permitted_uri_chars'],預設為:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_-';
根據實際需求擴充字元集,例如需支援中文 URL、括號、等號:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_-\u4e00-\u9fa5()='; // 注意:PHP 正則不直接支援 \u,實際請寫入實際字元或使用 PCRE Unicode 屬性
實務建議: 使用 a-z 0-9~%.:_- 基礎上,視專案需求添加 @、+、=、& 等常見字元。切勿直接開放所有字元(如 .*),否則失去輸入過濾保護。
因為 Cookie 鍵名也經過 _clean_input_keys() 檢查。若舊 Cookie 含非法鍵名,每次請求都會觸發錯誤。清除 Cookie 後,該非法鍵名消失,錯誤自然消失。但這非根治,使用者再次寫入相同 Cookie 仍會復發。
permitted_uri_chars;定期清理舊版 Cookie。_clean_input_keys() 中加入錯誤日誌(記錄 $str 與 $_SERVER['REQUEST_URI']),快速定位問題來源。透過配置調整與前端規範雙管齊下,可徹底解決「Disallowed Key Characters」困擾,並保持框架安全防護機制有效運作。