echo中c.formfile("file")返回的*multipart.fileheader对象,其filename字段即客户端提交的原始文件名,未经服务端校验或清理,可能含路径、空格、unicode或恶意字符,不可直接用于存储或路径拼接。

用 c.FormFile() 拿到文件对象后,原始名称在 Filename 字段里
在 Echo 中,c.FormFile("file") 返回的是一个 *multipart.FileHeader 实例,不是文件内容本身。它的 Filename 字段就是客户端提交时的原始文件名(即用户电脑上看到的那个名字),和 $_FILES['file']['name'] 的行为一致。
注意:这个值来自 HTTP 请求头里的 Content-Disposition,未经服务端校验或清理,可能含路径、空格、Unicode 或恶意字符,不能直接用于存储或拼接路径。
- 示例中
file.Filename是"report.pdf",不是"C:\Users\Alice\Downloads\report.pdf"(浏览器会自动剥离路径) - 若用户上传名为
"../etc/passwd"的文件,file.Filename仍会返回该字符串——需手动过滤 - 不要用
file.Header.Get("Content-Disposition")手动解析,容易出错;直接读file.Filename
getName() 不是 Echo 自带方法,别跟 CodeIgniter 混了
有人搜 “Echo getName()” 是因为 CodeIgniter 4 的 UploadedFile 对象有 getName() 方法,但 Echo 没这玩意儿。Echo 的 *multipart.FileHeader 只有 Filename、Size、Header 和 Open() 四个公开字段/方法。
如果你看到某段代码调用了 file.getName() 并报错 undefined method getName,基本可以确定是把框架记混了。
Echo框架 5.1.0 版本源码包下载,适合关注 RealIP 行为变化、StartConfig.Listener、NewDefaultFS 和观测性中间件入口的开发团队。
- CodeIgniter 4:有
getName()、getRandomName()、getClientOriginalName() - Laravel:有
getClientOriginalName() - Echo:只有
file.Filename—— 简单、直接、没封装
想获取“最终保存名”?得自己生成,Echo 不管重命名逻辑
Echo 不提供自动重命名、冲突处理或文件移动功能。它只负责解析请求并给你一个 FileHeader。所谓“最终文件名”,是你调用 file.Open() 后,用 io.Copy() 或 os.WriteFile() 写入磁盘时自己决定的名字。
常见做法是基于原始名生成安全哈希名,比如:sha256(file.Filename + time.Now().String())[:16] + ".pdf",再拼上扩展名。
- 别依赖
file.Filename直接作为磁盘文件名,尤其当它含中文、空格或控制字符时 - 扩展名应从
file.Header.Get("Content-Type")或http.DetectContentType()推断,而非信任file.Filename的后缀 - 如果真要保留原始语义,建议把
file.Filename存进数据库,磁盘用随机名,二者通过 ID 关联
调试时怎么确认拿到的是原始名?打印整个 file 结构最靠谱
开发阶段最容易误判的地方,就是以为 file.Filename 被框架改过。其实没有。最稳妥的验证方式是用 spew.Dump(file) 或 fmt.Printf("%+v", file) 看输出,确认 Filename 字段值是否符合预期。
例如 curl 传 -F "file=@测试_文件.txt",输出中 Filename 应为 "测试_文件.txt"(UTF-8 编码),而不是乱码或被截断的字符串。
- 如果看到乱码,大概率是终端或日志系统编码不支持 UTF-8,不是 Echo 的问题
- 如果
Filename是空字符串,检查前端<input type="file">是否真的选中了文件,且表单 enctype 是multipart/form-data - Chrome 浏览器对某些特殊文件名(如纯空格)会静默替换为
"blob",这是浏览器行为,后端无法干预










