You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 9并发AJAX请求下会话数据丢失问题求助

会话竞态条件导致Laravel 9中部分会话变量丢失问题

问题场景

使用Laravel 9框架,会话存储采用Redis(此前为文件存储)。存在如下场景:

  • 控制器方法getReport将多组数据存入会话后返回视图
  • 视图通过3个DataTables实例同时发起AJAX请求,调用同一控制器的getAjaxData方法加载对应会话中的数据

当视图仅包含1个DataTables,或设置$.ajaxSetup({async: false})时功能正常;但同时发起2-3个请求时,前1-2个请求能成功返回数据,其余请求返回空白,对应会话变量丢失,现象不稳定,推测是竞态条件导致。

补充细节

  • AJAX对应的getAjaxData方法仅查询并返回JSON数据,不修改会话
  • 问题发生时用户未登出,仅丢失部分自定义会话变量;频繁刷新AJAX URL(如http://site.com/reports/ajax?key=12345)可稳定复现,缓慢刷新则不会出现
  • 会话未完全销毁:用户仍保持登录状态,失败的AJAX请求仍能通过customer守卫验证进入控制器,说明会话保留了token和守卫相关数据

数据存入会话的原因

这些数据生命周期较短(短于会话有效期),且各报表间存在交叉引用,需要统一查询处理;若让AJAX请求按需查询数据,会重复调用外部API并产生大量服务端额外处理开销。

已尝试的解决方案(均无效)

  • 从文件存储切换为Redis存储会话,无改善
  • 尝试为路由添加阻塞逻辑,无变化
  • 试用rairlie/laravel-locking-session扩展,但运行异常,且该库未针对Redis会话做测试
  • 禁用AJAX路由的CSRF验证,无效
  • 在getAjaxData方法中添加调试代码,发现请求失败时会话仅包含token和守卫数据,自定义的report*_data变量完全丢失

示例代码

ReportController.php

class ReportController extends Controller {
    function getReport(Request $request) {
        session()->put('report1_data', $jsonData1);
        session()->put('report2_data', $jsonData2);
        session()->put('report3_data', $jsonData3);
        return view('reports');
    }

    function getAjaxData(Request $request) {
        $result = json_decode(session()->get($request->get('key')), JSON_OBJECT_AS_ARRAY);
        return response()->json($result);
    }
}

reports.blade.php

$(document).ready(function(){
    $('#table_report1').DataTable({ 
        ajax: '{{ URL::route('reports.ajaxdata',['key'=>'report1_data']) }}'
    });
    $('#table_report2').DataTable({ 
        ajax: '{{ URL::route('reports.ajaxdata',['key'=>'report2_data']) }}'
    });
    $('#table_report3').DataTable({ 
        ajax: '{{ URL::route('reports.ajaxdata',['key'=>'report3_data']) }}'
    });
});

web.php

Route::group(['middleware'=>['auth:customer']],function() {
    Route::controller(\App\Http\Controllers\ReportController::class)->group(function(){
        Route::get('reports','getReport')->name('reports');
        Route::get('ajax','getAjaxData')->name('reports.ajaxdata');
    });
});

内容的提问来源于stack exchange,提问作者localhost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 02:57:31