根本原因是PHP和Nginx在请求入口层拦截,需同步调大upload_max_filesize、post_max_size(后者≥前者)、client_max_body_size,并验证upload_tmp_dir权限;最优解是分片上传,前端切片+唯一标识,后端用$content接收、Redis校验、合并校哈希。

大文件 POST 提交失败,根本不在 Laravel 层,而是在 PHP 和 Nginx 的第一道关卡就被拦截了。直接调大限制不是最优解,容易引发超时、内存溢出或安全风险;真正可靠的方案是分片上传 + 前后端协同校验。
先过 PHP 和 Nginx 的硬限制关
上传失败常表现为 413、500 或静默截断,此时请求甚至没进 Laravel。必须同步调整三处:
-
php.ini:设
upload_max_filesize = 200M、post_max_size = 200M(必须 ≥ upload 值)、max_execution_time = 600、max_input_time = 600 -
Nginx 配置:在 server 或 location 块中加
client_max_body_size 200M; - 改完后务必重启 PHP-FPM(或 Apache),仅 reload 不生效
检查临时目录和权限是否就绪
即使参数调大,PHP 仍可能因临时目录不可写而丢弃文件,导致 $request->file('xxx') 返回 null,且无明显报错。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 用
ini_get('upload_tmp_dir')查路径,再用is_writable()验证可写性 - Docker 环境常见问题:挂载的 tmp 目录未给
www-data权限 - 运行
df -h确保磁盘空间充足
用分片上传绕过单次体积限制
前端切片(如每片 5MB),每片走独立 POST 请求,后端不拼接、只存分片,彻底避开 post_max_size 限制。
- 前端带上唯一
identifier(推荐文件 SHA256)、chunkIndex、totalChunks、filename - 后端接收时不走
$request->file()(易爆内存),改用$request->getContent()写入磁盘 - 用 Redis 记录已上传分片数:
Redis::incr("upload:{$identifier}:uploaded_chunks") - 最后一片到达后,校验总数是否匹配,再按序合并并核对最终文件哈希
补充 CSRF 和表单基础项
大文件上传失败有时表面是 419 或 403,实则是安全机制误拦。
- 确保表单含
@csrf,且method="POST"显式声明(不能省略) - 必须设置
enctype="multipart/form-data",否则文件字段不会被发送 - 若用 AJAX,需在 headers 中传
X-CSRF-TOKEN,不能只靠 meta 标签










