將動態頁面靜態化 (生成 HTML) 可大幅降低伺服器負載,但失去了即時判斷用戶登入狀態的能力。本文介紹一種經典的 <script src="login.php"> 跨域載入方案:靜態頁面引入動態 PHP 腳本,PHP 依 Cookie 狀態輸出 document.write() 顯示登入/未登入介面,兼容不支援 AJAX 的舊環境。
index.html) 嵌入 <script src="/loginajax.php?fid=xxx"></script>loginajax.php,自動攜帶網域 Cookie$_COOKIE['vvg'] 判斷登入狀態document.write('...HTML 片段...')index.html<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>靜態頁面即時調用登入狀態</title>
</head>
<body>
<!-- 登入狀態顯示區域 -->
<div id="login-status"></div>
<!-- 載入動態登入檢測腳本 -->
<script language="javascript" src="/loginajax.php?fid=123"></script>
</body>
</html>
loginajax.php<?php
header("Content-Type: application/javascript; charset=gb2312");
$fid = isset($_GET['fid']) ? intval($_GET['fid']) : 0;
// 判斷登入 Cookie (假設登入後設定 vvg 與 realname)
if (!isset($_COOKIE['vvg'])) {
// 未登入:顯示登入表單
?>
document.write('\
<form action="/login/login.php" method="post">\
用戶名:<input type="text" name="username" id="username" class="pl_sty1" />\
密碼:<input type="password" name="password" class="pl_sty1" />\
<input type="hidden" name="action" value="login" />\
<input type="hidden" name="fid" value="<?= $fid ?>" />\
<input type="submit" value="登入" />\
</form>\
');
<?php
} else {
// 已登入:顯示用戶名與登出連結
$realname = isset($_COOKIE['realname']) ? addslashes($_COOKIE['realname']) : '用戶';
?>
document.write('\
歡迎回來,<strong><?= $realname ?></strong> \
<a href="/login/login.php?action=logout">退出</a>\
');
<?php
}
?>
| 項目 | 說明 |
|---|---|
| Content-Type | 必須設為 application/javascript 或 text/javascript,否則瀏覽器可能不執行 |
| 字元編碼 | 靜態頁與動態腳本編碼必須一致 (範例均為 gb2312),否則中文會亂碼 |
| 輸出格式 | 所有 HTML 必須以 document.write('...') 輸出,單引號內的換行需用 \ 續行 |
| 跳脫處理 | 動態內容 (如用戶名) 必須經 addslashes() 或 json_encode() 處理,防止 JS 語法錯誤 |
| 快取控制 | 建議加入 header('Cache-Control: no-cache, must-revalidate') 避免瀏覽器快取舊狀態 |
document.write 會阻塞頁面渲染、難以維護複雜 UI、不利 SEO、無法在 defer/async 模式下正常運作| 方案 | 原理 | 優點 | 缺點 |
|---|---|---|---|
| Script 標籤 (本文) | JS 載入 PHP 輸出 document.write | 相容性最好、無需 CORS | 阻塞渲染、維護困難 |
| AJAX + JSONP | $.getJSON 跨域請求回調 | 非阻塞、資料與視圖分離 | 需支援 JSONP、舊瀏覽器受限 |
| AJAX + CORS | 後端設定 Access-Control-Allow-Origin | 標準化、支援完整 HTTP 動詞 | IE8/9 需 XDomainRequest |
| Edge Side Includes (ESI) | Nginx/Varnish 邊緣組合片段 | 真正的靜態化、效能最佳 | 需基礎設施支援、配置複雜 |
| Client-side Rendering (Vue/React) | 前端框架接 API 渲染 | 體驗最好、關注點分離 | 首屏較慢、SEO 需 SSR |
若專案仍在使用此方案,建議漸進式遷移至 AJAX + CORS:
Access-Control-Allow-Origin: * (或指定網域)fetch('/api/user/status', {credentials: 'include'}) 取得 JSONinnerHTML 渲染登入狀態區塊<script> 方案作為舊瀏覽器降級備案此方案雖屬經典老派技術,但在不支援現代前端工具鏈的老舊專案維護中仍具參考價值。