Laravel文件夹及内容上传问题:后端仅识别文件无法获取文件夹
Laravel 文件夹及内容上传解决方案
当使用webkitdirectory/directory属性上传文件夹时,浏览器不会单独传递文件夹实体,而是将每个文件的完整相对路径(如folder/sub/file.txt)作为文件名的一部分发送。Laravel默认不会自动解析这个路径重建文件夹层级,所以后端只能看到文件,无法识别文件夹结构。以下是实现完整文件夹上传的步骤:
一、前端代码确认(无需大幅修改)
你的前端代码已正确使用文件夹上传属性,可补充兼容性属性覆盖更多浏览器:
<form action="{{route('documents.upload.folder')}}" method="post" enctype="multipart/form-data"> @csrf <input type="file" name="file[]" directory webkitdirectory mozdirectory msdirectory multiple> <button type="submit">Upload</button> </form> <script> const form = document.querySelector('form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const formData = new FormData(form); const response = await fetch('{{route('documents.upload.folder')}}', { method: 'POST', body: formData, }); console.log(await response.json()); }); </script>
二、后端Laravel处理逻辑
在对应控制器方法中,解析每个文件的相对路径,重建文件夹结构并保存文件:
方法1:使用File门面手动创建目录
use Illuminate\Http\Request; use Illuminate\Support\Facades\File; public function uploadFolder(Request $request) { // 验证上传文件合法性 $request->validate([ 'file.*' => 'required|file', ]); // 定义存储根目录(示例:storage/app/public/uploads) $rootDir = storage_path('app/public/uploads'); foreach ($request->file('file') as $file) { // 获取浏览器传递的完整文件路径(包含文件夹层级) $fullFilePath = $file->getClientOriginalName(); // 拆分路径和文件名 [ $folderPath, $fileName ] = array_values(pathinfo($fullFilePath)); // 递归创建目标文件夹(若路径不是根目录) if ($folderPath !== '.') { $targetDir = $rootDir . '/' . $folderPath; if (!File::exists($targetDir)) { File::makeDirectory($targetDir, 0755, true); } } // 移动文件到对应文件夹 $file->move($rootDir . '/' . $folderPath, $fileName); } return response()->json(['status' => 'success', 'message' => '文件夹及内容上传完成']); }
方法2:使用Storage门面(更符合Laravel规范)
若已配置public磁盘(默认存储在storage/app/public),可通过Storage门面简化操作:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; public function uploadFolder(Request $request) { $request->validate([ 'file.*' => 'required|file', ]); foreach ($request->file('file') as $file) { $fullFilePath = $file->getClientOriginalName(); // 自动处理文件夹创建与文件存储 Storage::disk('public')->putFileAs( dirname($fullFilePath), $file, basename($fullFilePath) ); } return response()->json(['status' => 'success', 'message' => '上传完成']); }
注意事项
- 确保存储目录(如
storage/app/public/uploads)具备写入权限,可通过chmod -R 755 storage/命令设置。 - 若需对外访问上传的文件,需执行
php artisan storage:link创建软链接到public/storage。
内容的提问来源于stack exchange,提问作者Sharif
相关产品推荐
相关产品推荐

