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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:17:29