許多開發者誤以為 PHP Session 必須依賴 Cookie。實際上,PHP 提供了 透明 Session ID 傳遞 機制:當檢測到客戶端禁用 Cookie 時,可自動將 Session ID 附加到 URL 或表單隱藏字段,實現無 Cookie 會話追蹤。本文通過實測代碼驗證該機制,並探討跨窗口 Session 共享方案。
PHPSESSID 的 Cookie 中,瀏覽器自動攜帶。?PHPSESSID=... 附加到所有相對鏈接、表單 action、甚至靜態 HTML 鏈接中。--enable-trans-sid(Windows 版預設開啟,Linux 需重新編譯)。php.ini 設置 session.use_trans_sid = 1(PHP 7.1+ 默認關閉)。session.use_cookies = 1、session.use_only_cookies = 0。<?php
// test1.php
session_start();
$_SESSION['url'] = 'test2.php';
echo '<a href="' . $_SESSION['url'] . '">goto test2.php</a>';
?>
<?php
// test2.php
session_start();
if (isset($_SESSION['url'])) {
echo 'congratulations. ';
echo '<a href="test1.php">goto test1.php</a>';
} else {
echo 'failed.';
}
?>
瀏覽器禁用 Cookie 後訪問 test1.php,鼠標懸停鏈接可見:https://host/test2.php?PHPSESSID=6e3610749f7ded3784bc4a4dd10f879b。查看頁面源碼,即使鏈接寫在 PHP 標籤外的純 HTML 中,PHP 依然自動重寫,證明重寫發生在輸出緩衝階段,與瀏覽器無關。
session_start(),即使頁面只有 HTML,也要在頂部 <?php session_start(); ?>。https://)不會被重寫,需手動拼接 SID 常量。<form method="POST"> 會自動插入 <input type="hidden" name="PHPSESSID" value="...">。session.cookie_domain = .example.com 並確保同協議。現象:即使啟用 Cookie,JS window.open() 或 target="_blank" 打開的新窗口在 IE/Edge 早期版本中屬於新進程,無法讀取父窗口的 Session Cookie(進程級 Cookie)。
解決方案:
window.open('page.php?' . SID)。session_id($cookieVal); session_start();。use_only_cookies=1),防止 Session ID 洩露在 URL/日誌/Referer 中。session.cookie_httponly = 1、session.cookie_secure = 1(HTTPS)。session_regenerate_id(true) 防固定攻擊。總結:PHP Session 不強制依賴 Cookie,透過 --enable-trans-sid 與配置可實現 URL 透明傳遞;但出於安全與體驗,生產環境建議 Cookie 為主、URL 為輔,並妥善處理跨窗口共享問題。