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

Laravel集成FilePond分片上传:如何获取PATCH请求内容?

FilePond + Laravel 分片上传:获取PATCH请求内容的解决方案

问题描述

有没有开发者尝试过使用FilePond与Laravel实现文件分片上传?我正尝试完成该功能,但不知道如何获取PATCH请求的内容。上传启动后会收到多个PATCH请求,在Firefox开发者工具的网络面板中可以看到这些请求因offset不同而存在差异。

我的Blade视图代码

<form action="{{ route('upload.store') }}" enctype="multipart/form-data"
    method="post">
    @csrf
    <input class="" id="imageUploadFilePond" name="file" type="file">
    <button class="btn btn-primary" type="submit">Submit</button>
</form>
@push('scripts')
    <script src="https://unpkg.com/filepond@^4/dist/filepond.js"></script>
    <script>
        const inputElement = document.querySelector('#imageUploadFilePond');

        const pond = FilePond.create(inputElement, {
            server: {
                url: '/upload',
                patch: "/",
                headers: {
                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
                },
            },
            chunkUploads: true,
            chunkSize: 1048576,
            chunkForce: true,
        });
    </script>
@endpush

我的UploadController.php代码

public function store(Request $request)
{
    if ($request->file === '{}') {
        return uniqid();
    }
    return '';
}

public function update(Request $request, $id)
{
    $uploadOffset = $request->header('upload-offset');
    $uploadLenght = $request->header('upload-length');
    $uploadName = $request->header('upload-name');
    $numberOfChunks = $uploadLenght / self::CHUNKSIZE;
    $currentChunk = $uploadOffset / self::CHUNKSIZE;

    return $id;
}

解决方法:获取PATCH请求的分片内容

FilePond的分片PATCH请求内容是以原始二进制数据流传递的,无法通过常规表单字段方法获取,需按以下方式处理:

  1. 读取分片原始内容
    在update方法中,用$request->getContent()直接获取分片的二进制数据:

    $chunkContent = $request->getContent();
    
  2. 完善分片存储与合并逻辑
    将每个分片追加写入临时文件,全部上传完成后合并为最终文件:

    const CHUNKSIZE = 1048576; // 与前端chunkSize保持一致(1MB)
    
    public function update(Request $request, $id)
    {
        $uploadOffset = (int)$request->header('upload-offset');
        $uploadLength = (int)$request->header('upload-length');
        $uploadName = $request->header('upload-name');
        
        // 临时文件路径,用上传ID确保唯一性
        $tempFilePath = storage_path('app/temp/' . $id);
        
        // 创建临时目录(不存在则创建)
        if (!file_exists(dirname($tempFilePath))) {
            mkdir(dirname($tempFilePath), 0755, true);
        }
        
        // 定位到offset位置写入分片内容
        $fileHandle = fopen($tempFilePath, 'c');
        fseek($fileHandle, $uploadOffset);
        fwrite($fileHandle, $request->getContent());
        fclose($fileHandle);
        
        // 检查是否所有分片上传完成
        $currentSize = filesize($tempFilePath);
        if ($currentSize === $uploadLength) {
            // 移动临时文件到最终存储目录
            $finalPath = storage_path('app/uploads/' . $uploadName);
            rename($tempFilePath, $finalPath);
            
            // 可添加数据库记录等后续逻辑
            return response()->json(['status' => 'completed', 'path' => $finalPath]);
        }
        
        return response()->json(['status' => 'chunk_received'], 200);
    }
    
  3. 修正前端FilePond配置
    server.patch需指向包含上传ID的路由,确保分片请求能携带唯一标识:

    server: {
        url: '/upload',
        patch: "/:id", // 绑定上传ID参数
        headers: {
            'X-CSRF-TOKEN': '{{ csrf_token() }}'
        },
    },
    
  4. 配置正确的路由
    确保路由支持POST(初始化上传)和PATCH(上传分片)请求:

    Route::post('/upload', [UploadController::class, 'store'])->name('upload.store');
    Route::patch('/upload/{id}', [UploadController::class, 'update'])->name('upload.update');
    
  5. 优化初始化请求处理
    完善store方法,提前创建临时文件避免权限问题:

    public function store(Request $request)
    {
        if ($request->input('file') === '{}') {
            $uploadId = uniqid();
            // 初始化空临时文件
            $tempFilePath = storage_path('app/temp/' . $uploadId);
            touch($tempFilePath);
            return $uploadId;
        }
        
        // 非分片上传的处理逻辑(可选)
        return '';
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:40:31