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

AJAX 中文亂碼徹底解決方案:IE 與 Firefox 雙瀏覽器相容實戰

     編輯:PHP 相關知識

AJAX 請求傳遞中文參數時,編碼不一致是導致亂碼的主因。本文針對「頁面編碼為 GB2312/Big5,AJAX 預設以 UTF-8 發送」的經典場景,提供經實測在 IE 與 Firefox 均正常運作的完整解決方案,涵蓋前端編碼、後端解碼與轉碼的雙重處理流程。

問題根源分析

  • AJAX 強制 UTF-8:XMLHttpRequest 發送資料時預設以 UTF-8 編碼
  • 頁面非 UTF-8:舊專案常使用 GB2312/Big5,瀏覽器按頁面編碼解碼回應
  • 瀏覽器差異:IE 對未編碼的中文參數容錯較高,Firefox 嚴格遵循 UTF-8 導致亂碼

完整解決方案(兩步走)

步驟 1:前端雙重編碼(關鍵!)

// 取得使用者輸入或欲發送的中文參數
var param = document.getElementById('keyword').value;

// 必須雙重 encodeURI!單次在 IE 會導致參數值為空
param = encodeURI(encodeURI(param));
// 或寫成兩行
// param = encodeURI(param);
// param = encodeURI(param);

var url = 'search.php?kw=' + param;
xmlhttp.open('GET', url, true);
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send(null);

為什麼要雙重編碼?
IE 在送出前會自動依頁面編碼(如 GB2312)對 URL 進行一次編碼,Firefox 不會。若只 encodeURI 一次:
- Firefox:送出 UTF-8 編碼 → 正常
- IE:送出「UTF-8 編碼後再 GB2312 編碼」→ 後端解碼失敗
雙重編碼後,Firefox 送出「雙重 UTF-8」,IE 送出「雙重 UTF-8 + GB2312」,後端統一做「URL 解碼 → UTF-8 轉目標編碼」即可雙贏。

步驟 2:後端解碼與轉碼順序固定

<?php
header('Content-Type: text/html; charset=GB2312'); // 宣告回應編碼

$kw = $_GET['kw'] ?? '';

// 1. 先 URL 解碼(還原雙重編碼)
$kw = urldecode($kw);

// 2. 再由 UTF-8 轉目標編碼(GB2312/Big5/UTF-8)
$kw = iconv('UTF-8', 'GB2312//IGNORE', $kw);

// 現在 $kw 可正常用於 SQL 查詢、輸出等
$sql = "SELECT * FROM products WHERE name LIKE '%$kw%'"; // 實務請用預處理
?>

順序鐵律:urldecode() 必須在 iconv() 之前!反之會產生錯誤字元導致轉碼失敗。

回應端中文輸出亂碼解決

若伺服器回應中文給 AJAX,需明確宣告回應編碼:

<?php
// PHP
header('Content-Type: text/html; charset=UTF-8'); // 或 GB2312
echo "中文內容";

或在 AJAX 回呼中強制指定:

xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        // 若回應為 XML
        var xmlDoc = xmlhttp.responseXML;
        // 若回應為純文字
        var text = xmlhttp.responseText;
    }
};

現代專案建議:全站 UTF-8

新專案強烈建議:

  1. 資料庫、表、欄位全用 utf8mb4
  2. PHP 檔案儲存為 UTF-8 無 BOM
  3. HTML <meta charset="UTF-8">
  4. PHP header('Content-Type: application/json; charset=UTF-8')
  5. 前端直接 encodeURIComponent() 單次即可

全鏈路 UTF-8 可徹底消除編碼地獄,僅在維護舊系統時需用本文方案。

常見坑點檢查表

  • ☐ 前端是否 encodeURI(encodeURI()) 雙重編碼?
  • ☐ 後端是否先 urldecode() 再 iconv()?
  • ☐ iconv 目標編碼是否與頁面/資料庫一致?
  • ☐ 是否在 iconv 加上 //IGNORE 或 //TRANSLIT 避免非法字元中斷?
  • ☐ 回應 Header 是否正確宣告 charset?
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved