0

0

如何使用Golang实现文件上传与下载_Golang Web文件上传与下载实战

P粉602998670

P粉602998670

发布时间:2026-03-13 01:25:23

|

890人浏览过

|

来源于php中文网

原创

http.FileServer 仅支持 GET 请求用于静态文件分发,不支持文件上传;上传需手动解析 multipart/form-data,调用 r.ParseMultipartForm(32 << 20) 并处理表单数据。

如何使用golang实现文件上传与下载_golang web文件上传与下载实战

Go 的 http.FileServer 不能直接用于上传

很多人看到 http.FileServer 就以为能传文件,其实它只处理 GET 请求,负责静态文件分发,对 POST 或表单上传完全无感知。真正上传必须手动解析 multipart/form-data 请求体。

关键点:

  • r.ParseMultipartForm(32 预分配内存(32MB 是常见上限,超限会报 <code>http: request body too large
  • r.MultipartForm.File 返回的是 map[string][]*multipart.FileHeader,注意是切片 —— 即使单文件也要取 [0]
  • 别直接用 fileHeader.Open() 后 defer fclose:如果后续解码失败或校验不通过,文件可能已写一半,得先校验再开

保存上传文件时务必检查 FileHeader.Size 和扩展名

攻击者可伪造 Content-Type、修改后缀、甚至传恶意可执行文件。仅靠 fileHeader.Header.Get("Content-Type") 不可靠,它只是客户端声明的 MIME 类型。

实操建议:

立即学习go语言免费学习笔记(深入)”;

  • fileHeader.Size > 10 拒绝超 10MB 的文件(按需调整)
  • filepath.Base(fileHeader.Filename) 提取原始名,再用 strings.ToLower(filepath.Ext(name)) 取小写后缀
  • 白名单校验:if !slices.Contains([]string{".jpg", ".png", ".pdf"}, ext) { http.Error(w, "unsupported file type", http.StatusBadRequest); return }
  • 保存路径用 filepath.Join(uploadDir, uuid.NewString()+ext),避免原名冲突和路径遍历(../../etc/passwd 类攻击)

下载文件要用 http.ServeContent 而非 http.ServeFile

http.ServeFile 简单但危险:它不做路径净化,若请求 /download?name=../config.yaml 可能泄露任意文件。而 http.ServeContent 允许你完全控制读取逻辑,并支持断点续传(Range 头)。

典型用法:

Yodayo
Yodayo

一个专为动漫迷和vTuber打造的AI艺术创作平台、交流社区

下载
fi, err := os.Stat(filePath)
if os.IsNotExist(err) {
    http.Error(w, "file not found", http.StatusNotFound)
    return
}
w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filepath.Base(filePath)))
w.Header().Set("Content-Type", "application/octet-stream")
http.ServeContent(w, r, filepath.Base(filePath), fi.ModTime(), bytes.NewReader(data))

注意:http.ServeContent 第四个参数是 modtime,它影响 Last-Modified 和缓存协商;第五个是 io.ReadSeeker,不能传普通 []byte —— 得包装成 bytes.NewReader(data) 或打开文件后用 os.File(它实现了 io.ReadSeeker)。

大文件上传/下载要设超时并流式处理

默认 HTTP 超时(如 30 秒)对百 MB 文件根本不够,且一次性读进内存会 OOM。必须流式 + 显式超时。

上传侧:

  • 在 handler 开头加 ctx, cancel := context.WithTimeout(r.Context(), 5*time.Minute),后续所有 IO 操作都用该 ctx
  • fileHeader.Open() 得到 io.Reader 后,用 io.CopyN(dst, src, size) 或带 buffer 的 io.Copy,避免全量加载

下载侧:

  • 设置 w.(http.Flusher).Flush() 配合 bufio.NewWriterSize(w, 64 控制缓冲区大小
  • 不要用 ioutil.ReadFile 加载整个文件再写 —— 改用 http.ServeContentio.Copy 直接从 *os.File 流式输出

边界情况容易被忽略:客户端中断连接时,io.Copy 会返回 net/http: request canceled,此时应主动 cancel() 并清理临时资源(比如未完成的上传文件)。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

210

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

247

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

356

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

409

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

201

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1458

2025.06.17

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 6.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号