<?php
// 錯誤 1:直接輸出變數,單引號破壞 JS 語法
echo "<script>test('$_POST[userid]');</script>";
// 錯誤 2:雙引號內插變數,同樣有注入風險
$para = "hello boby!";
echo "<script> var para=\"$para\"; alert(para);</script>";
後果:使用者輸入 ' ; alert(1) // 即可導致 XSS 攻擊。
json_encode() + 資料屬性<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="app" data-user-id="<?= htmlspecialchars(json_encode($userId), ENT_QUOTES, 'UTF-8') ?>"></div>
<script>
// 讀取:自動解析為 JS 物件/字串/數值
const userId = JSON.parse(document.getElementById('app').dataset.userId);
console.log(userId);
</script>
</body>
</html>
<?php
$userData = [
'id' => 123,
'name' => "O'Reilly", // 單引號
'roles' => ['admin', 'editor'],
'settings' => (object)['theme' => 'dark', 'lang' => 'zh-TW'],
];
// json_encode 會正確處理編碼、轉義、型別
$jsVar = json_encode($userData, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);
?>
| 旗標 | 作用 |
|---|---|
JSON_HEX_TAG | < > 轉為 \u003C \u003E,防 </script> 截斷 |
JSON_HEX_APOS | 單引號轉 \u0027 |
JSON_HEX_QUOT | 雙引號轉 \u0022 |
JSON_HEX_AMP | & 轉 \u0026 |
JSON_UNESCAPED_UNICODE | 中文不轉 \uXXXX,較易閱讀 |
PHP 7.3+ 可直接用 JSON_THROW_ON_ERROR 捕獲編碼失敗。
<?php
session_start();
$csrfToken = $_SESSION['csrf_token'] ?? bin2hex(random_bytes(32));
?>
header('Content-Type: application/json'); echo json_encode($data);window.__INITIAL_STATE__。json_encode() 將 PHP 變數序列化為 JS 常值。htmlspecialchars(..., ENT_QUOTES) 雙重保護。data-* 屬性或 <script type="application/json"> 隔離資料與邏輯。