File API 不解析 EXIF,需用 FileReader 读取 ArrayBuffer 后通过 DataView 解析 JPEG/TIFF 文件头中的 APP1 段;必须由用户主动选择文件,仅支持 image/jpeg 或 image/tiff,推荐优先使用 exif-js 库。

File API 本身不解析 EXIF,它只负责把用户选中的文件安全地读进内存;真正提取 EXIF 需要配合底层二进制解析逻辑——但整个过程必须严格限定在用户主动授权范围内,不能绕过沙箱。
只能读用户亲手选的文件
浏览器禁止脚本直接访问本地路径或任意文件。所有 EXIF 提取起点,必须是用户通过 <input type="file"> 点选、或拖放操作产生的 File 对象。拿到 e.target.files[0] 后,务必先检查 files.length > 0,否则会报错。
- 不支持
new File(["fake"], "photo.jpg")这类构造——它没有真实来源,无法触发 EXIF 解析所需的数据流 - 不能用 AJAX 或 fetch 加载本地
file://路径——现代浏览器会拦截并抛出 CORS 错误 - 拖放事件中需从
event.dataTransfer.files取值,同样要校验长度和类型(比如只处理image/jpeg)
用 FileReader 读原始字节
EXIF 数据藏在 JPEG/TIFF 文件头里,文本方式(readAsText)会破坏二进制结构。必须用 readAsArrayBuffer 获取原始字节,再用 DataView 按偏移量逐段解析。
- 监听
onload事件,从reader.result得到ArrayBuffer - 创建
new DataView(buffer),才能按字节序读取 TIFF Header、APP1 标记、IFD 偏移等关键字段 - 注意 JPEG 中 EXIF 通常位于
0xFFE1开头的 APP1 段,长度字段紧随其后,需跳过标记和长度再定位 IFD
轻量级方案优先选 exif-js
自己手写解析器容易漏掉厂商私有标签或边界情况。对多数前端场景,exif-js 是更稳的选择:它内置了 JPEG/TIFF 的头部扫描逻辑,支持从 <img> 元素或 File 对象提取,且自动处理方向、时间、GPS 等常用字段。
- 引入后调用
EXIF.getData(file, callback)即可,回调里的this.exifdata是完整对象 - 用
EXIF.getTag(this, "DateTimeOriginal")直接取拍摄时间,不用手动算偏移 - 若需更高性能或定制化(如只取方向),可改用原生
FileReader + DataView组合,但建议先验证type === "image/jpeg"
别忽略 MIME 类型和格式限制
不是所有图片都有 EXIF。PNG、GIF、WebP 通常不含标准 EXIF(部分 PNG 可能带 tEXt 块,但非通用);HEIC 在 Safari 中可能有,但兼容性差。实际处理前应做两层过滤:
- 检查
file.type是否为"image/jpeg"或"image/tiff" - 对 JPEG,可快速扫描前几百字节是否有
0xFFD8(SOI)和0xFFE1(APP1)标记,避免无效解析 - 解析失败时不要静默吞掉错误——返回明确提示,比如“该图片不含 EXIF 元数据”

















