Laravel 5.3在线测试项目:如何通过Ajax保持会话不超时?
解决Laravel 5.3长时在线测试的会话超时问题
嘿,这个场景我太熟悉了——3小时的在线测试,默认Laravel会话2小时的有效期肯定不够用,而且就算调长,用户中途盯着题目思考不动也会触发超时。完全可以用Ajax(或者现代的Fetch API)做个心跳机制来保持会话活跃,下面给你一套适配Laravel 5.3的具体方案:
第一步:先调整基础会话配置
首先得把会话的默认有效期拉到测试时长以上,不然心跳再勤快也没用:
- 打开项目根目录下的
config/session.php - 找到
lifetime参数,把默认的120(分钟)改成180(对应3小时) - 确认
expire_on_close设置为false,这样会话不会因为浏览器窗口意外关闭直接失效
第二步:前端实现心跳请求
写个简单的定时器,每隔一段时间给后端发个请求,触发Laravel自动刷新会话过期时间。建议把间隔设得比会话有效期短一些,比如9分钟(避免刚好卡在超时边缘):
// 放在测试页面的<script>标签里,或者单独的JS文件中 function keepSessionAlive() { // 用Fetch发送请求,记得带上会话Cookie fetch('/keep-alive', { method: 'GET', credentials: 'include' }) .then(() => console.log('会话已刷新')) .catch(err => console.warn('心跳请求失败:', err)); } // 页面加载完成后启动定时器,每隔540000毫秒(9分钟)执行一次 window.addEventListener('load', () => { setInterval(keepSessionAlive, 540000); });
第三步:后端配置路由和控制器
Laravel只要接收到带有有效会话Cookie的请求,就会自动刷新会话的过期时间,所以后端逻辑非常简单:
- 在
routes/web.php中添加心跳路由:
Route::get('/keep-alive', 'SessionController@keepAlive');
- 创建对应的控制器
SessionController:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class SessionController extends Controller { public function keepAlive(Request $request) { // 不需要复杂逻辑,只要返回正常响应即可 return response('会话已保持活跃', 200); } }
额外注意事项
- CSRF保护:如果把请求改成POST(更安全),记得在请求头里带上CSRF令牌,Laravel 5.3默认开启CSRF验证,你可以在页面头部加个meta标签:
然后在Fetch请求中添加headers:<meta name="csrf-token" content="{{ csrf_token() }}">headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content } - 服务器超时设置:如果你的服务器用了Nginx或者Apache,要确保它们的超时时间大于3小时,比如Nginx的
proxy_read_timeout、Apache的Timeout参数,避免服务器提前中断心跳请求。
这样一套组合下来,既能保证会话基础时长覆盖测试时间,又能通过心跳请求持续刷新会话,用户就算中途长时间不动笔思考,也不会因为会话被销毁导致测试提交失败了。
内容的提问来源于stack exchange,提问作者Deepesh singh
相关产品推荐
相关产品推荐

