常用文件扩展名对照表

文件扩展名(Extension)是文件名末尾的标识,提示文件类型与默认打开方式。本表覆盖开发中常见的文本、代码、图片、文档、音视频与字体扩展名及含义。

原理解析

文件扩展名(如 .txt、.png、.json)是文件名末尾的片段,historically 用来提示文件类型、让操作系统选择打开程序。但它只是「约定」,不保证内容真的匹配。

真正的类型判定靠内容签名(magic number)与 MIME 类型,而非扩展名。扩展名大小写不敏感(.PNG 等同 .png),但不同系统/语言对大小写敏感的文件系统会区分;同名扩展在不同语境下也可能指向完全不同的格式。

什么时候该查这张表

这张表在你要判断某个扩展名对应什么文件类型、能不能安全地在线预览时有用。它按文档、图片、音频视频、压缩包、代码与数据分类,给出扩展名、类型与说明。选上传白名单、判断预览策略时查它。

不该查的情况:你在做 MIME 类型的严格映射或服务端内容嗅探。扩展名与真实类型不是一回事(改个后缀就能骗过),安全判断必须读文件头字节而不是看扩展名。

判断标准:先问「要不要允许在线预览」。文本类(txt/md/csv/json)可直接渲染;图片要防 SVG(可含脚本)与 SVGZ;HTML 要防 XSS;PDF 要防内嵌 JS。能下载就不要预览是更安全的原则。

特别注意双扩展名攻击:foo.pdf.html 在某些服务端按第一个点截断,或反过来按最后一个扩展名判断类型。文件上传校验必须用完整文件名比对,不能只取最后一段。

边界与常见陷阱

  • 改后缀就能骗过基于扩展名的所有校验

    把 payload.html 改名成 payload.pdf,服务端只看扩展名就会用 PDF 处理器打开并渲染其中的脚本。真正的校验必须读文件头魔数:PNG 是 89 50 4E 47,PDF 是 25 50 44 46,JPEG 是 FF D8 FF,ZIP(也是 docx/xlsx 的容器)是 50 4B 03 04。安全实现要交叉验证:声明的类型、扩展名、魔数三者必须一致,任一不符就拒绝或转存为纯文本。

  • SVG 是最容易被忽略的可执行文件格式

    SVG 是 XML,可以内嵌 <script>、onload 事件与外部引用。直接把它当图片在 <img> 里渲染相对安全,但用 <object>/<iframe>/内联方式引入就会执行脚本。SVGZ 更是「gzip 压缩的 SVG」,扩展名完全不提示其内容。策略:上传时用 ImageMagick 等工具转成 PNG 或剥离脚本元素;或者只允许白名单里的 SVG 特性(禁 script、foreignObject、on* 事件)。

  • 文件名本身是攻击面,双扩展名与路径穿越都要防

    三类常见手法:① 双扩展名(shell.php.jpg)—— 某些服务端按第一个点截断,Apache 配错也会执行;② 路径穿越(../../etc/passwd)—— 未规范化就用原始文件名;③ 同形字/特殊字符(全角字符、零宽字符、RTL override)—— 肉眼看起来是 .jpg 实际是 .php‍。防护:只取 basename 并做白名单字符过滤、扩展名用白名单而非黑名单、重命名存储为随机 ID 而非原始名。

与相邻内容的分工

要查文件类型对应的 HTTP Content-Type 与 MIME 映射,用站内「MIME 类型」页;本页关注文件本身而非传输声明。

要处理具体图片文件(压缩、转换、批量处理),用站内图片工具;本页是类型判别而非处理。

要设计上传接口的存储策略(对象存储、CDN、病毒扫描),属后端架构范畴,本表不覆盖。

若目的是排查某个文件为什么打不开,先读魔数确认真实类型——扩展名与内容不符是最常见原因。

实战片段

要点:① 扩展名可以随意改写,校验必须读文件头魔数(PNG 89 50 4E 47 / PDF 25 50 44 46 / ZIP 50 4B 03 04),且扩展名、魔数、声明类型三者需一致;② SVG 是最容易被忽略的可执行格式,能内嵌 script 与 on* 事件,SVGZ 更是压缩版毫无提示,务必转码或剥离;③ 文件名本身是攻击面 —— 双扩展名、路径穿越、零宽字符三类要同时防,扩展名用白名单而非黑名单;④ 存储一律用随机 ID,原始文件名只用于展示,从根上消除目录遍历。

// ① 魔数识别(比扩展名可靠)
const MAGIC = [
  { ext: 'png',  bytes: [0x89, 0x50, 0x4e, 0x47] },
  { ext: 'jpg',  bytes: [0xff, 0xd8, 0xff] },
  { ext: 'pdf',  bytes: [0x25, 0x50, 0x44, 0x46] },
  { ext: 'zip',  bytes: [0x50, 0x4b, 0x03, 0x04] },  // 也是 docx/xlsx 容器
  { ext: 'gif',  bytes: [0x47, 0x49, 0x46, 0x38] },
  { ext: 'elf',  bytes: [0x7f, 0x45, 0x4c, 0x46] },
]

function sniffMime(file) {
  const b = new Uint8Array(file.slice(0, 16))
  for (const m of MAGIC) {
    if (m.bytes.every((v, i) => b[i] === v)) return m.ext
  }
  return 'unknown'
}

// ② 交叉验证:扩展名 + 魔数 + 声明类型必须一致
const ALLOW = new Set(['png', 'jpg', 'pdf'])
async function safeCheck(file) {
  const ext = file.name.split('.').pop().toLowerCase()
  const magic = sniffMime(file)
  if (!ALLOW.has(magic)) throw new Error('魔数不在白名单: ' + magic)
  if (ext !== magic) throw new Error('扩展名与内容不符: ' + ext + ' vs ' + magic)
  return true   // ✅ 三者一致才放行
}

// ③ 🔴 文件名净化:防双扩展名 / 路径穿越 / 零宽字符
function safeName(raw) {
  let n = raw.split(/[\/]/).pop()          // 取 basename,丢弃路径
  n = n.replace(/[​-‍]/g, '')  // 零宽字符
  n = n.replace(/../g, '')                   // 路径穿越残留
  const parts = n.split('.')
  const ext = parts.pop().toLowerCase()
  const base = parts.join('.')               // ← 保留全部中间段,双扩展名才拦得住
  if (!/^[a-zA-Z0-9_-]+$/.test(base)) throw new Error('非法文件名')
  if (!ALLOW.has(ext)) throw new Error('扩展名不允许')
  return base + '.' + ext
}
console.log(safeName('shell.php.jpg'))       // 抛错(双扩展名)
console.log(safeName('../../etc/passwd'))   // passwd(无扩展名→抛错)

// ④ 存储用随机 ID,不用原始文件名(防目录遍历与信息泄露)
import { randomUUID } from 'crypto'
const stored = randomUUID() + '.' + ext
console.log('原名仅作展示,存储名:', stored)

// ⑤ SVG 要特别处理
const DANGEROUS_SVG = /<(script|foreignObject)|sonw+=/i
if (file.name.endsWith('.svg') && DANGEROUS_SVG.test(await file.text())) {
  throw new Error('SVG 含脚本或事件处理器,拒绝')
}

实践注解

  • 扩展名只是建议,不能当作校验依据把 a.exe 改名成 a.jpg 后扩展名就骗过了白名单。文件类型必须靠内容魔数(magic bytes)判定,扩展名最多作为展示与默认打开方式的提示。
  • .tar.gz 与 .tgz 是同一格式,双扩展名要成对处理只看最后一段扩展名会得到 gz,误判为单个 gzip 流。解压逻辑应先识别 .tar.gz/.tar.bz2/.tar.xz 这类组合,再决定是否需要二次解包。
  • 大小写在 Windows 与 Linux 上不一致Windows 文件系统不区分大小写,(IMAGE.PNG 与 image.png 同名);Linux 区分。做跨平台文件匹配时应统一转小写比较,否则同一份资产在两个平台上会匹配到不同文件。

数据来源

  • IANA Media Types
  • Platform and tooling conventions (no unified registry)

上述编号、名称与定义均来自公开规范,本站不主张对规范数据本身的独创性;本页的编排方式、中文释义与实践注解由本站撰写。

扩展名类型说明
.txt文本纯文本文件
.md文本Markdown 标记文本
.htmlWeb超文本标记语言页面
.htmWebHTML 页面(短扩展名)
.cssWeb层叠样式表
.js代码JavaScript 脚本
.ts代码TypeScript 源码
.json数据JSON 数据
.xml数据可扩展标记语言
.csv数据逗号分隔值表格
.yaml数据YAML 配置/数据
.yml数据YAML 配置/数据(短名)
.toml数据TOML 配置
.png图片无损位图(支持透明)
.jpg图片JPEG 有损压缩图
.jpeg图片JPEG 有损压缩图
.gif图片动图/无损位图
.webp图片现代高效图片格式
.svg图片矢量图形
.ico图片图标(favicon)
.pdf文档便携式文档
.doc文档Word 旧版文档
.docx文档Word 文档(OOXML)
.xls文档Excel 旧版表格
.xlsx文档Excel 表格(OOXML)
.ppt文档PowerPoint 旧版演示
.pptx文档PowerPoint 演示(OOXML)
.zip压缩ZIP 压缩包
.rar压缩RAR 压缩包
.7z压缩7-Zip 压缩包
.tar压缩TAR 归档(常配合 .gz)
.gz压缩Gzip 压缩
.mp3音频MPEG 音频
.wav音频无损波形音频
.mp4视频MPEG-4 视频
.avi视频AVI 视频容器
.mov视频QuickTime 视频
.woff字体Web 开放字体格式
.woff2字体Web 开放字体格式 2(更高压缩)
.ttf字体TrueType 字体
.otf字体OpenType 字体
.exe程序Windows 可执行文件
.dll程序动态链接库
.apk程序Android 安装包
.iso镜像光盘镜像
.log文本日志文件
.env配置环境变量配置
.sql数据SQL 脚本
.db数据SQLite 数据库
.sqlite数据SQLite 数据库

常见问题

扩展名和 MIME 类型有什么关系?

扩展名是文件名末尾的标识(如 .png),MIME 类型(如 image/png)是传输时声明内容格式的标准。服务器响应常根据扩展名设置 Content-Type,浏览器据此决定如何解析。二者并非一一对应,但多数常见扩展名有约定俗成的 MIME。

哪些图片格式适合网页?

照片用 .jpg/.webp,需透明用 .png,图标/插画用 .svg,动图用 .gif。现代站点优先 .webp 以减小体积、提升加载速度。

.docx 和 .doc 有什么不同?

.doc 是 Word 旧的二进制格式;.docx 是基于 XML 的 OOXML 压缩包格式,体积更小、更不易损坏,现代 Word 默认使用 .docx。

为什么有些文件下载后是 .zip 但其实是代码?

扩展名只影响默认打开方式,不决定真实内容。压缩包、数据集甚至恶意载荷都可能用任意扩展名。判断真实类型应看文件头(magic number)或 MIME,而非扩展名。