go 1.16+ 需用 http.fs(os.dirfs("./data")) 替代 http.dir("./data") 启用目录浏览;上传大文件前须调用 r.parsemultipartform(32

怎么用 http.FileServer 快速启动目录浏览服务
直接用 http.FileServer 能跑起来,但默认不支持目录列表(返回 403),因为 Go 1.16+ 默认禁用了 fs.FS 的隐式目录遍历。必须显式传入支持 ReadDir 的文件系统。
- 别写
http.ListenAndServe(":8080", http.FileServer(http.Dir("./data")))—— 这在 Go 1.16+ 会静默失败,浏览器只看到空白页或 403 - 正确做法是包装成
http.FileSystem:用http.FS(os.DirFS("./data")),它自带ReadDir支持 - 如果路径含中文或空格,
http.FileServer会自动 URL 解码,但前端链接需确保 UTF-8 编码,否则点击乱码文件名会 404 - 注意权限:运行进程必须对
./data有读取权限,Linux 下常见坑是 SELinux 或 systemd 限制了网络服务访问文件系统
http.ListenAndServe(":8080", http.FileServer(http.FS(os.DirFS("./data"))))
上传文件时怎么避免内存爆掉和临时文件残留
request.ParseMultipartForm 默认把整个上传体读进内存,大文件(比如 >32MB)直接 OOM;不清理 multipart.File 句柄还会导致磁盘临时文件不释放。
- 务必在调用
ParseMultipartForm前设上限:r.ParseMultipartForm(32 (32MB),超出直接返回 <code>http.ErrMissingFile或自定义错误 -
file, header, err := r.FormFile("file")返回的file是multipart.File,本质是 *os.File,必须defer file.Close(),否则句柄泄漏、tmp 文件卡在磁盘 - 别用
ioutil.ReadAll(file)读大文件——改用io.Copy(dst, file)流式写入目标路径,边读边写 - 上传目标路径要校验:
filepath.Clean(header.Filename)防止../../etc/passwd路径穿越,再拼到白名单根目录下
预览文本/图片/JSON 文件时怎么安全判断 MIME 类型
不能信客户端传来的 Content-Type,也不能只看后缀名——攻击者可上传 shell.php.jpg 绕过检查。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 用
net/http.DetectContentType检测前 512 字节内容,但它对图片识别不准(尤其 WebP、AVIF),建议搭配github.com/h2non/filetype - 文本类(
.txt,.log,.json)可直接io.ReadFull读前几 KB,用utf8.Valid判断是否合法 UTF-8,避免二进制文件当文本渲染出错 - 图片预览别直接
<img src="/files/xxx">——先用image.DecodeConfig校验是否真为图片,防止 DOS(超大宽高值触发解码器崩溃) - JSON 文件建议加
Content-Type: application/json; charset=utf-8响应头,并设置X-Content-Type-Options: nosniff防 MIME sniffing
为什么下载大文件总卡住或断连,http.ServeContent 怎么用才稳
直接 io.Copy(w, f) 下载大文件,没设超时、没处理客户端中断、没发 Content-Length,Nginx 反代时还容易被截断。
- 必须用
http.ServeContent:它自动处理If-Modified-Since、Range请求(支持断点续传)、计算ETag,且内部用io.CopyBuffer流式传输 - 调用前需
f.Stat()获取os.FileInfo,传给http.ServeContent第三个参数;时间戳要用ModTime(),别用CreateTime()(Windows 不可靠) - 响应头里加
w.Header().Set("Content-Disposition", `attachment; filename="`+filename+`"`)强制下载,否则浏览器可能尝试内嵌预览 - 如果文件路径来自用户输入,
filepath.Join(root, relpath)后必须strings.HasPrefix(absPath, root)校验,防越权读取
事情说清了就结束
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










