
mime-db 实战把扩展名与 MIME 类型的映射变成确定答案【免费下载链接】mime-dbMedia Type Database项目地址: https://gitcode.com/gh_mirrors/mi/mime-db你八成也遇到过这种局面上传接口返回了一个文件浏览器却把它当成乱码文本渲染排查半天发现只是 Content-Type 写错了。这次的侥幸掩盖了一个事实——文件扩展名与 MIME 类型之间的映射并没有一份人人随手可查、且持续保鲜的权威清单。mime-db 就是为此而生的 Media Type 数据库它把 IANA、Apache、Nginx 三处来源注册的类型汇总进一个 JSON 文件一次 require 之后MIME 类型查询、扩展名反向查询、压缩判断都能当场给出答案。浏览器只看 Content-Type猜测式映射迟早要还债请求到达时浏览器只认 Content-Type 响应头来决定怎么渲染——当图片、当文本、当脚本执行。不少项目的做法是手写一张映射表从网上抄一份、向同事要一份能跑就行。问题在于这张表是静态的而 IANA 一直在注册新类型、废弃旧类型两边的差距会随时间越拉越大直到某天有人撞上类型写对了、浏览器却渲染错了的怪现象。真正该修的是数据层不是那几行处理请求的代码。你想要的是一份持续从多个来源同步、覆盖两千六百多个类型、且不带任何运行时逻辑的数据源——require 进来就能用。这正是 mime-db 的设计取向整个包就是一个公开的 JSON 文件不掺业务代码让数据尽量保持中立用法由你自己决定。打开 db.json一个 Media Type 条目里有什么项目根目录的db.json是整个库的入口结构是一个扁平对象键为全小写的 MIME 类型值为一个字段很少的对象。以 text/html 为例一条记录长这样text/html: { source: iana, compressible: true, extensions: [html, htm, shtml] }字段拆开看source记录类型的出处取值 iana、apache、nginx 三种缺省说明是社区补充的自定义类型。extensions是关联扩展名数组顺序有意义——首元素是默认推荐项生成这类文件时取extensions[0]最稳妥。compressible是布尔值表示该类型的典型文件是否值得 gzip别小看这个字段一个布尔值就能决定网关要不要为这个请求挂压缩。charset只在类型有默认字符集时出现比如 application/json 固定为 UTF-8。测试套件还强制了几个细节库内类型名全部小写、扩展名全部小写、扩展名数组不许为空。查询前把输入转小写能少踩一大类坑。正向查、反查、判压缩三条查询路径怎么走 正向查询最直接包的导出就是那个 JSON 对象本身拿类型字符串取键即可连中间层都不需要经过。不那么直接的是反查手里只有扩展名要找回它对应的类型。库没有内置这个 API但一条遍历 extensions 字段的表达式就够用——上面这条遍历解决的就是 MIME 类型反向查询const db require(mime-db) // 正向类型 - 完整信息 db[text/css].extensions // [css] // 反向扩展名 - 类型一次遍历即可 Object.entries(db) .find(([, d]) d.extensions?.includes(mkv))?.[0] // video/x-matroska第三条路径是压缩判断一个可选链就能覆盖const gzipWorthy (t) !!db[t]?.compressible gzipWorthy(text/css) // true gzipWorthy(image/png) // false gzipWorthy(x/foo) // false未命中时自然兜底最后一行顺手就是兜底类型查不到时表达式自然得 false不必额外判空。反查则相反未命中时find返回 undefined得在业务层自己补一个默认值。数据保鲜三个抓取脚本拼出的更新链路 ⚡数据只有保鲜才有价值。scripts/目录下的三个脚本各管一个来源scripts/fetch-iana.js从 IANA 拉取注册 CSV遇到带模板页的类型还会继续抓页面提取默认字符集和声明的扩展名fetch-apache.js与fetch-nginx.js分别抓取 Apache 和 Nginx 官方仓库里的 mime.types 配置文件。抓取结果落到src/目录各存一份*-types.json。构建环节接手收尾把src/下三份来源数据加上custom-types.json、custom-suffix.json两个自定义文件合并成最终的 db.json顺带过滤掉已废弃的类型。合并时自定义条目优先级最高这也是社区注册新类型时不去动上游数据的原因。custom-suffix.json里藏了个小聪明它按后缀批量声明比如所有json结尾的类型统一标记可压缩省去逐个标注。对维护者来说这条链路就是 mime-db 数据更新的全部两条命令走完npm run fetch # 拉取三个上游来源 npm run build # 合并生成 db.json # 或者一条命令搞定 npm run update普通使用者不必关心这条链路定期升级依赖版本新类型会自动随版本进来。踩坑笔记冲突、兜底与大小写类型冲突合并时的优先级多个来源声明同一类型、扩展名又不一致时别凭记忆猜该留哪个——构建脚本已有定论自定义条目优先级最高覆盖任何上游来源对同类型的声明db.json 里最终只留合并后的结果。想在项目层面改映射有两条路把类型提交到src/custom-types.json再重建影响所有使用者或者在自己的服务里对 db 包一层覆盖只影响自己。前者适合形成社区共识后者适合私有定制。未知类型与大小写兜底怎么给查不到的类型默认回落到application/octet-stream让浏览器按文件下载而不是尝试渲染反查未命中时同理在业务层补默认值。测试套件还保证了库内类型名与扩展名全为小写上游传来大小写混杂的头部值时先转小写再查否则必然落空。另留个心同一个扩展名可能挂在多个类型下反查只会返回第一个命中的业务敏感时把全部命中筛出来再选。从 clone 到第一次查询只要三条命令 想先摸一遍数据长相最短路径是克隆仓库直接打开全程不需要装依赖git clone https://gitcode.com/gh_mirrors/mi/mime-db cd mime-db node -e console.log(require(./db.json)[application/json])输出{ source: iana, charset: UTF-8, compressible: true, extensions: [json, map] }这就是你的第一次 MIME 类型查询。生产环境里把require(./db.json)换成require(mime-db)其余一行不用改。mime-db 把 MIME 类型查询从凭记忆、凭旧表变成一次确定性的查表而查表可信的前提是数据始终跟着上游走。【免费下载链接】mime-dbMedia Type Database项目地址: https://gitcode.com/gh_mirrors/mi/mime-db创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考