把文件上传到一个基于服务器的转换器,三件事会发生。你的文件通过网络传输到你无法控制的某个 IP 地址。服务器上的某个进程解码它。然后,取决于网站的保留策略,文件会留在磁盘上——短则几分钟,长则永久。
同样的事情在浏览器标签页里做,文件不会离开你机器的内存。解码器运行在浏览器引擎强制执行的 WebAssembly 沙箱内。网络从未被触及。
这不仅是策略差异,更是架构差异。基于服务器的转换器可以承诺删除你的文件;浏览器端的转换器无法泄露你的文件,因为它从一开始就从未收到过它们。
架构
客户端转换由四个层次组成:
第 1 层:文件访问
当你拖放一个文件到浏览器标签页时,DragEvent 或 <input type="file"> 会给 JavaScript 一个 File 对象。File 不是文件的内容,而是一个引用:包含文件名、大小、MIME 类型,以及一个按需从磁盘读取字节到内存的方法(file.arrayBuffer())。
在这个方法被调用之前,零字节被移动。文件安静地躺在你的文件系统里。浏览器的文件选择器是操作系统级别的对话框,网页只能看到用户明确选择的 File 对象。
第 2 层:格式检测
任何文件的前几个字节都能可靠地标识其格式。JPEG 以 FF D8 FF 开头。PNG 以 89 50 4E 47 开头。HEIC 文件包含一个 ftyp box,在偏移量 8 处带有 heic 或 heif 品牌标记。
读取文件头(通常是前 32 个字节)足以确认它到底是什么,无论扩展名是什么。这项检查在任何解码器接触像素数据之前执行。如果文件头不匹配,文件立即被拒绝。没有浪费的 CPU 周期,也不会在解码到一半时弹出令人困惑的错误信息。
第 3 层:解码
原始字节通过解码器变成像素。用哪个解码器取决于格式:
- JPEG、PNG、WebP、BMP:浏览器自带这些格式的原生解码器。
createImageBitmap()将压缩字节交给操作系统的编解码器(Windows 上是 Windows Imaging Component,macOS 上是 Core Graphics,Linux/ChromeOS 上是 Skia),返回原始像素数据。这条路径速度快,在操作系统支持的地方有硬件加速,且不需要额外代码。 - HEIC:除 Safari 外,没有浏览器自带 HEIC 原生解码器。我们的转换器内置了 libheif——一个编译为 WebAssembly 的 C 库。
.wasm二进制文件(~1.2 MB 压缩后)下载一次后缓存。它在 WASM 沙箱内将 HEIF/HEIC 文件解码为原始 RGB 像素。 - PDF:PDF.js(Mozilla 的 PDF 渲染器)将每一页以请求的分辨率渲染到画布。没有服务端渲染。PDF 从未离开浏览器。
每个解码器从内存读取、向内存写入。没有解码器会打开 socket。WASM 沙箱尤其无法发起网络请求:浏览器不会向 WebAssembly 模块暴露网络 API。即使 C 代码调用了 socket(),沙箱也会拦截它。
第 4 层:编码
原始像素进入 <canvas> 元素的 2D 上下文。canvas.toBlob() 或 canvas.toDataURL() 调用浏览器的内置编码器输出 JPG、PNG 或 WebP。编码器是平台原生代码:和你的操作系统保存截图用的是同一条代码路径。
输出是一个 Blob——内存中的字节缓冲区。它被交给下载链接,或者打包进一个用 JavaScript 构建的 ZIP 压缩包。在整个过程中,没有任何字节触碰到网络 socket。
浏览器强制执行了什么
网页运行在浏览器在引擎层面维护的沙箱内。这不是礼貌协议,而是由进程隔离强制执行的:
渲染器进程:JavaScript 引擎、DOM 和 WASM 运行时运行在一个沙箱化进程中,没有直接的文件系统或网络访问权限。它通过 IPC 与浏览器进程通信。
站点隔离:现代浏览器将每个来源放在自己独立的渲染器进程中。你在 file-convert-factory.org 中的文件对于运行在任何其他域名上的 JavaScript 是不可见的。
WASM 沙箱:WebAssembly 模块只能看到一块平坦的线性内存缓冲区,别无他物。没有文件系统 API,没有 fetch(除非 JavaScript 显式导入),没有访问 DOM 或其他浏览器 API 的权限。一个被攻破的 WASM 模块最坏的情况是破坏自己的内存,让标签页崩溃。
相比之下,基于服务器的转换器以特权进程运行在服务器的操作系统上。它可以读磁盘、写磁盘、打开网络连接、派生子进程。安全模型取决于服务器运营者的能力和意图。浏览器沙箱只取决于浏览器引擎的正确性,而浏览器沙箱是软件领域中被审计最严格的安全边界之一。
基于服务器的转换器承诺(和不承诺)什么
基于服务器的转换器本身并不恶毒。很多是由善意的团队运营的。问题出在结构上:
- 上传步骤就是一次复制。你的文件现在存在于两个地方。你控制一个副本,别人控制另一个。
- 删除是一个承诺。"我们 24 小时后删除文件"意味着你要信任那行日志、那个定时任务、备份系统和每个有服务器权限的员工。这些都无法从外部验证。
- 元数据随文件一同传输。你照片的 EXIF 数据(GPS 坐标、相机序列号、时间戳)属于文件字节的一部分。文件上传了,元数据也就上传了。我们的 EXIF 隐私指南详细介绍了里面到底有什么以及如何去除。简单来说:本站的每个转换器都会去除元数据,因为它解码像素再重新编码,丢弃了所有不属于图像数据的内容。
- HTTPS 保护的是传输管道,不是端点。TLS 加密上传过程中的数据,但对于文件到达后发生的事情无能为力。
浏览器端转换器的隐私保证更窄但更强。它说的是:你的文件不会离开你的设备,因为不存在让它们离开的代码路径。这是可验证的。转换文件时打开 DevTools 的 Network(网络)面板,你会看到 WASM 二进制文件加载一次后就再也没有任何网络请求。零字节上传。没有对 /api/convert 的请求。没有 WebSocket 流量。转换完全在渲染器进程内发生。
亲自验证
你不必相信任何人的说辞。打开 Chrome DevTools(F12),切换到 Network 面板,然后在任何工具页面上转换一个文件。你能看到的唯一网络活动:
- 页面 HTML、CSS 和 JavaScript:首次访问时加载一次。
- WASM 二进制文件(针对 HEIC 转换器):加载一次,之后缓存。
- 分析请求(如果你没有屏蔽的话)。
没有任何文件数据离开浏览器。每个请求的 Content-Length 单位是 KB,不是 MB。任何会用 DevTools 的人都可以独立验证这一点。
对于基于服务器的服务,你无法做同样的断言。你上传文件,得到结果,然后你只能相信服务器确实删除了它。
相关工具
本站的每一个转换器都遵循这套架构。流水线(拖放、验证、解码、编码、下载)在所有 23 个工具上运行方式完全一致:
- HEIC 转 JPG · HEIC 转 PNG · HEIC 转 WebP
- JPG 转 PNG · JPG 转 WebP · JPG 转 ICO
- PNG 转 JPG · PNG 转 WebP · PNG 转 ICO
- WebP 转 JPG · WebP 转 PNG · WebP 转 ICO
- BMP 转 JPG · BMP 转 PNG · BMP 转 WebP · BMP 转 ICO
- PDF 转 JPG · PDF 转 PNG · PDF 转 WebP
- 图片转文字 (OCR):同样的客户端架构,在 WASM 中运行 Tesseract
关于 WASM 沙箱的技术细节,参见我们的 WebAssembly 详解。想深入了解你照片携带了什么元数据,EXIF 隐私指南会逐字节地教你读取和去除它们。



