AJAX 原生僅支援字串傳輸,若需傳遞陣列、物件等結構化資料,業界標準做法是後端 json_encode 序列化為 JSON 字串,前端 JSON.parse 反序列化。本文以「課程上課狀態即時檢查」為例,示範完整流程。
function ajaxCheckedLessons() {
$lessonIds = [3583, 1500, 2717, 1612]; // 國文8、國文9、物理8、物理9
$where = ['lessons.id IN(?)' => $lessonIds];
$all = (new Dao_Lessons())->getLessons($where);
$result = [];
foreach ($all as $lesson) {
$key = '';
if ($lesson['id'] == 3583) $key = '8yuwen';
elseif ($lesson['id'] == 1500) $key = '9yuwen';
elseif ($lesson['id'] == 2717) $key = '8wuli';
elseif ($lesson['id'] == 1612) $key = '9wuli';
$result[$key] = verifyCheckedLessons($lesson['startime'], $lesson['endtime']); // 回傳 true/false
}
echo json_encode($result); // {"8yuwen":true,"9yuwen":false,"8wuli":true,"9wuli":false}
}
$.ajax({
type: 'POST',
url: '/default/index/ajaxcheckedlessons',
data: '',
success: function(response) {
if (!response) return alert('error');
var data = JSON.parse(response); // 推薦:原生 JSON.parse,安全、效能佳
// var data = eval('(' + response + ')'); // 舊寫法,有 XSS 風險,勿用
$('#8yuwen').css('color', data['8yuwen'] ? 'red' : '');
$('#9yuwen').css('color', data['9yuwen'] ? 'red' : '');
$('#8wuli').css('color', data['8wuli'] ? 'red' : '');
$('#9wuli').css('color', data['9wuli'] ? 'red' : '');
},
error: function(xhr, status, err) {
console.error('AJAX 失敗:', status, err);
}
});
| 方法 | 安全性 | 效能 | 備註 |
|---|---|---|---|
JSON.parse(str) | 高(僅解析 JSON 子集) | 高(原生 C 實作) | 現代標準,IE8+ 全支援 |
eval('('+str+')') | 低(執行任意 JS 代碼) | 中 | 僅限極舊環境(IE6/7)且完全信任來源時使用 |
jQuery.parseJSON(str) | 高 | 高 | 內部呼叫 JSON.parse,jQuery 3.0+ 已棄用 |
interface LessonStatus {
'8yuwen': boolean;
'9yuwen': boolean;
'8wuli': boolean;
'9wuli': boolean;
}
const data = JSON.parse(response) as LessonStatus;
if (data['8yuwen']) { ... } // 編譯期型別檢查
echo json_encode($arr) 前有 var_dump、echo 除錯輸出 → 導致 JSON 格式錯誤。解法:ob_clean() 或確保無輸出。DateTime 物件 → json_encode 失敗。解法:實作 JsonSerializable 或先轉字串/時間戳。json_encode 預設不轉義 Unicode,輸出 中文 而非 \u4e2d\u6587,傳輸量更小,前端直接可用。