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必须为Onsession.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
相关产品推荐
相关产品推荐

