AJAX (XMLHttpRequest) 內部強制使用 UTF-8 編碼發送/接收數據。GB2312 頁面直接發送中文參數會導致服務端接收亂碼;服務端返回 GB2312 數據,前端按 UTF-8 解析也會亂碼。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<script>
// UTF-8 字符串轉 GBK 字節數組 (用於發送)
function utf8ToGbkBytes(str) {
// 簡易實現:利用瀏覽器內置編碼器(需頁面為 GBK)
// 實際項目建議使用 iconv-lite / encoding.js 庫
return str; // 此處省略,重點在接收端
}
// GBK 字節數組轉 UTF-16 字符串 (用於接收顯示)
function gbkBytesToUtf16(bytes) {
// 核心:將每個字節轉為 \uXXXX 格式
let result = '';
for (let i = 0; i < bytes.length; i++) {
result += '' + bytes.charCodeAt(i) + ';';
}
return result;
}
// 實戰封裝:AJAX 獲取學校列表
function loadSchools(type) {
const xhr = new XMLHttpRequest();
xhr.open('POST', 'ajax.php', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
// 關鍵:響應文本按 GBK 解碼為 UTF-16 實體
const gbkText = xhr.responseText;
const utf16Html = gbkToHtmlEntities(gbkText);
document.getElementById('schoolList').innerHTML = utf16Html;
}
};
xhr.send('type=' + encodeURIComponent(type));
}
// GBK 字符串 -> HTML 實體 (瀏覽器自動渲染為中文)
function gbkToHtmlEntities(str) {
let html = '';
for (let i = 0; i < str.length; i++) {
const code = str.charCodeAt(i);
if (code > 127) { // 非 ASCII,視為 GBK 雙字節高位
// 簡易處理:實際需完整 GBK 解碼器
html += '' + code + ';';
} else {
html += str[i];
}
}
return html;
}
</script>
</head>
<body>
<select onchange="loadSchools(this.value)">
<option value="1">小學</option>
<option value="2">初中</option>
</select>
<div id="schoolList"></div>
</body>
</html>
<?php
header('Content-Type: text/html; charset=gb2312');
$type = $_POST['type'] ?? '1';
$data = [
1 => [['id'=>1, 'name'=>'紅旗小學'], ['id'=>2, 'name'=>'實驗小學']],
2 => [['id'=>3, 'name'=>'一中'], ['id'=>4, 'name'=>'二中']],
];
// 輸出 JS 數組字面量,前端 eval 解析
echo '[';
foreach ($data[$type] as $i => $s) {
if ($i) echo ',';
echo "['{$s['id']}', '{$s['name']}']";
}
echo ']';
?>
<meta charset="utf-8">header('Content-Type: application/json; charset=utf-8')SET NAMES utf8mb4fetch/axios 直接收發 JSON,零轉碼痛苦。Encoding.convert(str, 'UNICODE', 'GBK')new TextDecoder('gbk').decode(uint8Array)(需響應類型為 arraybuffer)。