mime.TypeByExtension 仅基于文件扩展名判断类型,速度快但不可靠,如将 evil.exe 改为 report.pdf 会误判为 application/pdf;它不读取文件内容,且默认映射有限,需手动调用 mime.AddExtensionType 扩展支持,推荐对关键场景使用 http.DetectContentType 基于文件头识别。

怎么用 mime.TypeByExtension 判断文件类型?
它只看后缀名,不读文件内容,所以快但不准。比如把 evil.exe 改成 report.pdf,mime.TypeByExtension 就会返回 application/pdf —— 完全不可信。
- 只适合内部可信场景,比如静态资源路由分发
- 对没有后缀的文件(如
README)返回空字符串 - 注意大小写:
.JPG和.jpg都能识别,但.jpeg比.jpg优先级低,返回的是image/jpeg而不是image/jpg - 常见漏掉的扩展名:
.webp(Go 1.19+ 才原生支持)、.avif(至今不支持)
为什么 mime.TypeByExtension 返回空,而文件明明有后缀?
因为 Go 的 mime 包默认只加载一小部分常用映射,且不自动读取系统 /etc/mime.types。你传入 .xyz,它查不到就直接返回空,不会 fallback 或报错。
- 检查是否拼错后缀:
.tar.gz不是标准扩展名,mime只认.gz(对应application/gzip),.tar是application/x-tar - 想支持更多类型,得手动注册:
mime.AddExtensionType(".xyz", "application/vnd.example") - 别在 init 函数里反复调用
AddExtensionType,重复注册会 panic
真要靠内容识别 MIME 类型,该用哪个函数?
用 mime.TypeByHeader 或更稳妥的 http.DetectContentType —— 它们读文件前 512 字节做 magic number 匹配。
-
http.DetectContentType是公开、稳定、推荐的 API;mime.TypeByHeader需要构造一个假的http.Header,麻烦且易错 - 它不保证 100% 准确:文本文件、JSON、YAML 都可能被识别为
text/plain - 对小文件(
- 示例:
http.DetectContentType([]byte("#!/bin/bash\necho hi"))返回text/plain; charset=utf-8,不是text/x-shellscript
生产环境识别文件类型,光靠 mime 包够吗?
不够。它只是基础工具,不是安全边界。
立即学习“go语言免费学习笔记(深入)”;
- 上传场景必须组合使用:先看后缀(快速过滤),再读头 512 字节校验(防伪装),最后按业务规则白名单检查(如只允许
image/*和application/pdf) - 注意
http.DetectContentType不处理压缩流:gzip 文件即使解压后是图片,它也只认 gzip 的 magic header(application/gzip) - 第三方库如
gabriel-vasile/mimetype支持嵌套检测(比如 zip 包里的 docx),但会增加依赖和 CPU 开销
真正难的不是调哪个函数,而是决定在哪个环节拒绝、哪个环节警告、哪个环节记录日志——这些没法靠 mime 包自动帮你做。










