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

Laravel中Dropify上传进度条无法获取Session数据求助

解决Laravel中Dropify上传进度条无法获取Session数据的问题

我来帮你一步步排查这个问题,核心问题大概率出在Laravel的Session封装逻辑和一些容易忽略的配置、请求细节上,咱们逐个解决:

1. 放弃直接使用原生$_SESSION,改用Laravel官方Session API

Laravel有自己的Session管理机制,默认情况下原生$_SESSION数组不会被自动填充(尤其是当你用了database/redis这类非file驱动时)。你必须用Laravel提供的方式访问Session数据:

修改你的控制器方法:

public function callSessionData(Request $request)
{
    // 获取Laravel封装的全部Session数据
    $sessionData = $request->session()->all();
    
    $prefix = ini_get("session.upload_progress.prefix");
    $sessionFieldName = ini_get("session.upload_progress.name");
    // 从请求中动态获取表单里的进度标识值,不要硬写"myForm"
    $uploadKey = $prefix . $request->input($sessionFieldName);
    
    if (!empty($sessionData[$uploadKey])) {
        $current = $sessionData[$uploadKey]["bytes_processed"];
        $total = $sessionData[$uploadKey]["content_length"];
        echo $current < $total ? ceil($current / $total * 100) : 100;
    } else {
        echo 100;
    }
}

这里改成动态获取表单里的进度标识,避免硬编码带来的拼写错误,也更符合PHP上传进度的设计逻辑。

2. 检查PHP上传进度的核心配置

先确认你的php.ini里开启了上传进度相关配置,可以临时在控制器里输出配置信息验证:

// 调试用,确认后删除
dd([
    'session.upload_progress.enabled' => ini_get('session.upload_progress.enabled'),
    'session.upload_progress.cleanup' => ini_get('session.upload_progress.cleanup'),
    'session.upload_progress.prefix' => ini_get('session.upload_progress.prefix'),
]);

关键配置要求:

  • session.upload_progress.enabled必须为On
  • session.upload_progress.cleanup建议设为Off(默认是On,会在请求结束后立即清理进度数据,异步轮询时可能还没拿到数据就被清空了)

修改配置后记得重启你的Web服务器。

3. 把Ajax改成轮询模式,而不是单次请求

你现在的Ajax只发了一次请求,根本赶不上上传进度的变化。应该用setInterval定时发送请求,直到进度达到100%:

// 拦截表单默认提交,启动轮询
$('#myForm').submit(function(e) {
    e.preventDefault();
    const form = $(this);
    const progressField = form.find('[name="{{ ini_get('session.upload_progress.name') }}"]');
    
    // 每500ms查询一次进度
    const progressInterval = setInterval(() => {
        $.ajax({
            type: "POST",
            url: "{{route('admin.templates.uploadprogress')}}",
            data: {
                "_token": "{{ csrf_token() }}",
                [progressField.attr('name')]: progressField.val()
            },
            success: function(progress) {
                // 更新进度条显示
                $('#bar_color').width(`${progress}%`);
                $('#status').text(`${progress}%`);
                
                // 进度完成后停止轮询,再提交表单
                if (progress >= 100) {
                    clearInterval(progressInterval);
                    form.unbind('submit').submit();
                }
            }
        });
    }, 500);
});

如果不想阻止表单同步提交(同步提交会刷新页面),可以考虑用iframe承载表单提交,这样页面不会刷新,轮询能正常进行。

4. 确认表单隐藏字段被正确提交

在控制器的callSessionData方法里先打印请求数据,确认进度标识字段被正确传递:

public function callSessionData(Request $request)
{
    dd($request->all()); // 检查是否包含session.upload_progress.name对应的字段
    // ... 其他代码
}

如果这个字段不存在,说明表单里的隐藏字段写得有问题,需要重新核对。

5. 验证Session驱动的可用性

如果你用的是Laravel的database或redisSession驱动,要确保这些服务正常运行,Session数据能正常读写;如果是file驱动,检查storage/framework/sessions目录的权限是否正确(需要Web服务器有读写权限)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:04:29