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

求助:使用laravel-chunk-upload分片上传大视频失败,分片丢失未合并

分片上传合并失败排查与解决

1. 检查合并逻辑的完整性

分片上传完成后,后端需要将所有分片合并为完整文件并移动到lessons目录,同时清理分片文件。如果分片目录被清空但目标文件未生成,大概率是合并逻辑出现异常:

  • 确认合并代码中所有分片都被正确读取:检查循环遍历分片的范围是否匹配totalChunks,resumable.js的chunkNumber通常从1开始,循环要从1到totalChunks,而非0开始。
  • 验证合并后的文件是否正确写入lessons目录:检查目标路径是否正确,比如使用storage_path('app/lessons/' . $fileName)而非相对路径。
  • 确保只有合并成功后才删除分片:避免合并过程中出错但分片已被删除,导致无法重试。

示例合并逻辑代码:

public function mergeChunks(Request $request)
{
    $fileName = $request->input('fileName');
    $totalChunks = $request->input('totalChunks');
    $finalPath = storage_path('app/lessons/' . $fileName);
    
    // 创建目标文件句柄
    $finalFile = fopen($finalPath, 'wb');
    if (!$finalFile) {
        \Log::error('无法创建目标文件: ' . $finalPath);
        return response()->json(['error' => '创建文件失败'], 500);
    }

    try {
        // 遍历所有分片并合并
        for ($i = 1; $i <= $totalChunks; $i++) {
            $chunkPath = storage_path("app/chunk/{$fileName}/chunk_{$i}");
            if (!file_exists($chunkPath)) {
                throw new \Exception("缺失分片: {$i}");
            }
            
            $chunkContent = file_get_contents($chunkPath);
            fwrite($finalFile, $chunkContent);
            unlink($chunkPath); // 删除单个分片
        }

        fclose($finalFile);
        rmdir(storage_path("app/chunk/{$fileName}")); // 删除分片目录
        return response()->json(['success' => true]);
    } catch (\Exception $e) {
        fclose($finalFile);
        unlink($finalPath); // 删除未完成的目标文件
        \Log::error('合并分片失败: ' . $e->getMessage());
        return response()->json(['error' => $e->getMessage()], 500);
    }
}

2. 验证目录权限

确保storage/app/chunk和storage/app/lessons目录拥有web服务器用户的读写权限:

  • Linux环境下,执行以下命令(假设web用户为www-data):
chown -R www-data:www-data storage/app/chunk storage/app/lessons
chmod -R 755 storage/app/chunk storage/app/lessons
  • Windows环境下,右键目录→属性→安全,给IIS/IUSR用户添加读写权限。

3. 检查后端路由与请求合法性

  • 确认resumable.js配置的target地址与后端路由完全匹配,且请求方法为POST。
  • 确保请求携带了Laravel所需的CSRF Token,否则合并请求会被框架拦截:
var resumable = new Resumable({
    target: '/api/upload/merge',
    chunkSize: 10 * 1024 * 1024,
    query: { _token: '{{ csrf_token() }}' } // 传递CSRF Token
});

4. 查看Laravel日志定位错误

检查storage/logs/laravel.log中的错误信息,比如:

  • Permission denied:目录权限不足
  • File not found:分片路径错误或缺失
  • Disk quota exceeded:磁盘空间不足
    日志会直接暴露合并过程中出现的具体问题。

5. 验证分片参数传递正确性

确保前端传递的chunkNumber、totalChunks、fileName等参数被后端正确接收,参数不匹配会导致合并逻辑跳过或错误。可以在后端添加日志记录参数:

\Log::info('分片上传参数', [
    'chunkNumber' => $request->input('chunkNumber'),
    'totalChunks' => $request->input('totalChunks'),
    'fileName' => $request->input('fileName')
]);

内容的提问来源于stack exchange,提问作者ahmed gamal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:47:08