
本文介绍一种基于浏览器 localstorage 的前端方案,用于区分用户是直接在地址栏输入 url 访问页面,还是通过站内导航(如 navbar)点击跳转,从而实现“仅拦截直接访问、放行内部跳转”的安全控制逻辑。
本文介绍一种基于浏览器 localstorage 的前端方案,用于区分用户是直接在地址栏输入 url 访问页面,还是通过站内导航(如 navbar)点击跳转,从而实现“仅拦截直接访问、放行内部跳转”的安全控制逻辑。
单纯依靠 PHP 服务端无法可靠判断请求来源是手动输入 URL 还是点击链接——因为两者均表现为标准的 HTTP GET 请求,$_SERVER['HTTP_REFERER'] 易被伪造且不可靠,而 SCRIPT_FILENAME 校验(如原代码)会无差别拦截所有直接脚本执行,包括合法的站内导航跳转。
因此,推荐采用前后端协同的轻量级方案:利用浏览器 localStorage 作为“可信跳转凭证”。核心思路是——仅当用户通过网站内部链接(如 navbar)触发跳转时,由 JavaScript 主动写入临时标识;页面加载时校验该标识,缺失则视为非法直链访问,执行重定向或拒绝响应。
✅ 实现步骤
-
为所有导航链接添加统一跳转逻辑(推荐封装为函数)
不要直接使用<a href="page.php"></a>,而是绑定点击事件并注入标识:
<!-- 示例 navbar -->
<nav>
<a href="#" onclick="navigateTo('dashboard.php')">仪表盘</a>
<a href="#" onclick="navigateTo('profile.php')">个人资料</a>
</nav>
<script>
function navigateTo(url) {
// 设置可信标识
localStorage.setItem('nav_jump', 'true');
// 延迟跳转确保标识已写入
setTimeout(() => {
window.location.href = url;
}, 0);
}
</script>-
在受保护页面顶部添加校验逻辑(建议置于
中)
页面加载时立即检查标识,并在完成加载后清除它,避免残留:
<script>
// 页面加载前校验
if (!localStorage.getItem('nav_jump')) {
// 非导航跳转 → 重定向至首页或显示提示
window.location.href = '/index.php';
// 或:document.body.innerHTML = '<h3>访问受限</h3>';
throw new Error('Direct access denied');
}
// 页面加载完成后清除标识(防止刷新仍通过)
window.addEventListener('load', () => {
localStorage.removeItem('nav_jump');
});
</script>⚠️ 注意事项:
- 此方案依赖客户端 JavaScript,禁用 JS 时失效(需配合服务端基础防护,如登录态校验);
localStorage是同源的,多标签页间共享,但刷新后若未清除标识可能导致误放行,因此务必在load后清除;- 不适用于 SEO 敏感页面(因搜索引擎爬虫无 JS 执行能力,将被重定向);
- 更高安全性场景应结合服务端会话(如
$_SESSION)+ 一次性 Token(如点击链接时生成并传参),但本方案在简单内部系统中平衡了开发效率与可用性。
总结:虽然无法 100% 精确识别“地址栏输入”行为,但通过 localStorage + 显式跳转控制,可有效拦截绝大多数非交互式直链访问,同时保障用户体验无缝。关键在于将“信任”从 URL 路径转移到可控的用户交互动作上。

















