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

Laravel升级至9后调用S3取文件报无法获取file_size错误如何解决

问题诱发原因

Laravel 9 底层依赖的文件系统抽象包 Flysystem 从 Laravel 5.8 时期使用的 1.x 版本升级到了 3.x 版本,S3 存储适配器的响应生成逻辑发生了不兼容变更:调用response()方法生成文件HTTP响应时,默认会先发起HeadObject请求拉取文件元数据(包含file_size、mime_type等字段),用来填充标准响应头。以下三类场景都会触发该报错:

  • 权限配置缺失:Laravel 5.8 时期的Flysystem 1版本调用response()时不会主动发起HeadObject请求,仅需要s3:GetObject权限即可正常运行,升级后新增的HeadObject请求要求IAM账号额外配置s3:HeadObject权限,没配权限就会拉取元数据失败。
  • 路径/基础配置错误:升级后Flysystem 3不会自动过滤文件路径的多余前导斜杠,如果s3磁盘的root配置、传入的$file_path带了多余斜杠,或者region、endpoint、bucket配置填错,会导致最终请求的文件路径不存在,自然无法获取文件大小。
  • 第三方兼容存储适配问题:如果使用的是非AWS官方的S3兼容存储(比如MinIO、各类云厂商的对象存储兼容S3接口),旧版本的存储适配器没有适配Flysystem 3的元数据拉取逻辑,无法正常返回file_size字段。
修复方案

按优先级依次尝试以下方案即可解决:

  • 基础校验排查:先通过AWS CLI或官方SDK测试当前密钥是否能正常访问目标路径文件、拉取元数据;打印Storage::disk('s3')->path($file_path)确认最终拼接的文件路径没有多余斜杠、前缀错误,和实际存储的文件路径完全匹配。
  • 全局配置兼容旧行为:在config/filesystems.php的s3磁盘配置数组中加入'disable_asserts' => true,该配置是Flysystem 3官方提供的兼容项,开启后会关闭自动拉取元数据做校验的逻辑,调用response()时直接返回文件流,和Laravel 5.8时期的运行逻辑完全一致,原有业务代码不需要做任何修改即可正常运行。
  • 手动构建响应:如果不想修改全局配置,可以替换原有response()的调用逻辑,直接读取文件内容手动构建响应,跳过自动拉取元数据的步骤,示例代码如下:
$fileContent = Storage::disk('s3')->get($file_path);
return response($fileContent, 200)
    ->header('Content-Type', Storage::disk('s3')->mimeType($file_path));
  • 升级第三方适配器:如果使用第三方S3兼容存储,将对应的存储适配器包升级到支持Flysystem 3的版本即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:06:23