Session 是 PHP 無狀態 HTTP 中維持登入狀態的標準機制。登出看似簡單(`session_destroy()`),實際上涉及 Session 資料銷毀、Cookie 清理、快取控制、頁面跳轉方式(特別是 `iframe` 框架頁)等細節。本文整理完整的登出最佳實踐,並解決框架頁跳轉失效的常見問題。
<?php
// logout.php
// 1. 啟動 Session(必須在輸出前)
session_start();
// 2. 清空 $_SESSION 陣列(可選,destroy 會移除伺服器端檔案)
$_SESSION = [];
// 3. 刪除 Session Cookie(預設名稱 PHPSESSID)
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(
session_name(),
'',
time() - 42000,
$params['path'],
$params['domain'],
$params['secure'],
$params['httponly']
);
}
// 4. 銷毀伺服器端 Session 檔案
session_destroy();
// 5. 防止瀏覽器快取登出後頁面
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
// 6. 輸出跳轉腳本
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>正在登出...</title>
</head>
<body>
<script>
alert('您已成功登出!');
// 關鍵:頂層視窗跳轉,支援 iframe 框架頁
(window.top || window).location.href = 'login.php';
</script>
<noscript>
<meta http-equiv="refresh" content="1;url=login.php">
請啟用 JavaScript 或 <a href="login.php">點此登入</a>。
</noscript>
</body>
</html>
// 僅在 iframe 內部跳轉,父頁面不變 location.href = 'login.php'; // 或 window.location.href = 'login.php';
// 強制頂層視窗跳轉 parent.location.href = 'login.php'; // 或更通用(支援多層巢狀 iframe) top.location.href = 'login.php'; // 現代寫法(避免跨域錯誤) (window.top || window).location.href = 'login.php';
window:當前 iframe 視窗parent:直接父視窗top:最頂層視窗(瀏覽器分頁)若登出頁面與父頁面**不同源**(域名/協定/埠不同),瀏覽器同源策略會阻擋 `top.location.href`,拋出 `SecurityError`。
| 場景 | 解決方案 |
|---|---|
| 同源 | 直接使用 `(window.top || window).location.href = 'login.php'` |
| 同主域不同子域 | 雙方設定 `document.domain = 'example.com'`(已棄用,Chrome 100+ 移除) |
| 完全跨域 | 1. 父頁面監聽 `postMessage` 2. 登出頁 `parent.postMessage({action:'logout'}, '*')` 3. 父頁收到訊息自行跳轉 |
| 誤區 | 正確觀念 |
|---|---|
| 只呼叫 `session_destroy()` 即可 | 需同時清空 `$_SESSION`、刪除 Cookie、防快取 |
| `unset($_SESSION)` 等同清空 | `unset` 會銷毀變數本身,後續無法寫入;應用 `$_SESSION = []` |
| 登出後立即 `header('Location: login.php')` | 若在框架頁中會導致 iframe 內跳轉,必須輸出 JS 導向 top |
| 關閉瀏覽器即登出 | Session Cookie 為會話級,關閉瀏覽器才失效;需主動登出功能 |