把合同、证件照或带密钥的接口日志丢进一个陌生的在线转换器之前,多数人心里都会犯嘀咕:它会不会把文件传到服务器上?「我们不保存您的文件」这种承诺听上去不错,但你没法验证。浏览器本地处理的价值恰恰在于:它把「信不信」变成了「能不能查」。
这篇文章从数据路径讲起,说明浏览器为什么有能力在本地完成这些任务,然后给出一套你自己就能做的自查步骤(Network 面板、离线测试、控制台脚本),列出哪些网络请求是正常的、哪些该警惕,最后讲本地处理保护不了什么,以及哪些场景根本不该用浏览器。文中的数字和行为都来自 ToolGarden 的源码,而不是营销话术。
一、关键区别:文件走的是哪条路
传统在线转换器的流程是:浏览器把文件上传到服务器,服务器处理,再把结果发回来下载。浏览器本地处理则是:页面把程序代码(HTML、JavaScript、WebAssembly、必要时的模型文件)下载下来之后,用这些代码直接读取你选中的文件、在本机完成计算、把结果交给你保存。判断标准只有一条:开始处理之后,你的文件内容有没有出现在任何网络请求里。
| 维度 | 服务器处理 | 浏览器本地处理 |
|---|---|---|
| 文件路径 | 上传 → 服务器 → 下载 | 读取 → 本机计算 → 保存,不经过网络 |
| 隐私暴露面 | 服务器日志、存储桶、队列、第三方服务都可能接触文件 | 文件只在当前标签页内存中;需要信任的是页面代码本身 |
| 速度瓶颈 | 上传与下载带宽 | 本机 CPU、内存与浏览器限制 |
| 文件大小 | 取决于服务端配额 | 取决于设备内存,工具会设上限(例如 ToolGarden 图片工具为 50MB) |
| 离线可用 | 不可用 | 页面和所需资源缓存之后,部分工具可离线使用 |
| 可验证性 | 只能相信隐私政策 | 可以用开发者工具直接观察网络请求 |
| 算力 | 可使用 GPU 集群和大模型 | 受限于用户设备,只能跑体积较小的模型 |
二、浏览器到底能在本地做什么
这些能力都是浏览器的标准接口,不依赖任何插件:
- File 与 Blob:通过文件选择器、拖放或粘贴读取文件,内容直接进入页面内存。预览用的是 URL.createObjectURL 生成的本地临时地址,不是网络地址。
- Canvas:解码图片、缩放、叠加文字、重新编码为 JPG、PNG、WebP。ToolGarden 的图片格式转换优先交给 Web Worker 执行,失败才回退到主线程,页面上也会注明本地 Worker 优先、文件不上传。
- Web Worker:把耗时计算放到后台线程,页面不会卡住。
- WebAssembly 与 ONNX Runtime:把原本在服务器上运行的解码器、编码器和 AI 模型搬到浏览器里。ToolGarden 的去水印使用 MI-GAN 和 LaMa 两个 ONNX 模型,在本地推理;首次使用时会下载模型文件(MI-GAN 约 28MB),之后推理不再把图片发给任何服务。
- MediaDevices:二维码识别可以直接打开摄像头,用 jsQR 在本地逐帧解码,视频帧不会离开设备。
- IndexedDB 与 Cache Storage:缓存模型和静态资源,让第二次使用更快,也是离线能力的基础。
三、三步自查:用 Network 面板证明「没有上传」
不要相信页面上的「隐私保护」徽章,自己查一次只需要两分钟。关键点是先让页面把程序资源全部加载完,再清空记录,然后才选文件,这样列表里剩下的就都是处理过程中产生的请求。
- 打开开发者工具(Windows 与 Linux 为 F12,macOS 为 Option + Command + I),切到 Network 面板,勾选 Preserve log。
- 先把页面和工具完整加载一遍,等请求停下来,点「清空」按钮(圆圈加斜线图标)。
- 选一个无害的样本文件执行转换,观察新增请求。用「Fetch/XHR」「WS」过滤,再切回「All」看一遍。
| 看到的请求 | 含义 | 是否可疑 |
|---|---|---|
| 没有任何新请求 | 处理完全在本地完成 | 最理想 |
| GET,加载 .wasm、.onnx、.js、字体 | 按需下载程序、模型或字体 | 正常,注意看方向是下载 |
| POST/PUT,请求体大小接近你的文件 | 文件内容被发出去了 | 确认是上传 |
| Content-Type 为 multipart/form-data | 典型的表单文件上传 | 高度可疑,除非是你主动提交的表单 |
| WebSocket 持续有帧 | 可能在流式传输数据 | 需看帧内容和大小 |
| 类型为 ping 或 beacon 的小请求 | 统计、错误上报 | 检查载荷是否包含文件名或内容 |
实例:用一个 20MB 的图片做测试
用一张 20MB 左右的图片测试时,如果选文件之后出现了一个 POST,请求体也是 20MB 上下,那就是上传无疑;如果列表里要么没有新请求,要么只有几百字节的统计 ping,那么 20MB 的数据没有从这个页面发出去。注意比较的是请求体(Network 面板的 Request payload 与 Size 列),而不是页面整体流量。
用控制台脚本补一道保险
有些上传发生在选文件之后的任意时刻,Network 面板又很长,肉眼容易漏。可以在控制台贴一段脚本,把页面主线程上的 fetch、XMLHttpRequest 和 sendBeacon 的载荷类型和大小都打印出来。
const describe = (b) =>
b == null ? 'none'
: b instanceof Blob ? 'Blob ' + b.size + 'B'
: b instanceof ArrayBuffer ? 'ArrayBuffer ' + b.byteLength + 'B'
: typeof b === 'string' ? 'string ' + b.length + ' chars'
: b.constructor.name;
const _fetch = window.fetch;
window.fetch = (input, init) => {
console.log('[net] fetch', input.url ?? String(input), describe(init?.body));
return _fetch(input, init);
};
const _send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function (body) {
console.log('[net] xhr', describe(body));
return _send.call(this, body);
};
if (navigator.sendBeacon) {
const _beacon = navigator.sendBeacon.bind(navigator);
navigator.sendBeacon = (url, data) => {
console.log('[net] beacon', url, describe(data));
return _beacon(url, data);
};
}局限要说清楚:这段脚本只覆盖主线程。如果处理发生在 Web Worker 里(ToolGarden 的图片转换就是),Worker 里的请求不会被它捕获,但 Network 面板仍然会列出。所以脚本是补充,不能替代 Network 面板。
离线测试:最干脆的证据
把页面和工具加载完(如果工具要下载模型,等模型下载完),然后在 Network 面板把节流选项切到 Offline,或者直接断开 Wi-Fi,再选文件处理。能正常得到结果,说明处理过程不依赖服务器。如果提示联网失败,要分辨是「首次需要下载模型或页面资源」,还是「处理本身必须访问服务器」,前者可以先联网加载一次再测,后者就是服务端处理。
四、哪些请求是正常的,不等于上传
本地处理不等于页面完全没有网络活动。以下几类都是正常的,关键是区分「下载程序」与「发送你的数据」:
- 页面与代码分块:打开工具页时下载的 HTML、JS、CSS。
- 模型与 WebAssembly:ToolGarden 的部分模型和运行时放在自己的站点目录里(如 OCR、图像增强、放大),去水印使用的 MI-GAN 与 LaMa 模型则是从 Hugging Face 下载,首次使用约 28MB 的 MI-GAN;这些都是下载,不会带上你的图片。
- 第三方脚本:如果站点接入了统计或广告,页面会产生额外请求。它们不应该包含文件内容,用上面的方法验证即可,不必凭印象判断。
- 字体和图标:多为 GET 请求,没有请求体。
五、本地处理保护什么,不保护什么
| 风险 | 本地处理能否缓解 | 说明 |
|---|---|---|
| 服务端日志、存储桶、队列里留下文件 | 能 | 文件根本没有到过服务器 |
| 传输过程被截获 | 基本能 | 没有上传就没有文件的传输过程,但页面代码本身仍然走 HTTPS |
| 页面代码被篡改或被恶意脚本注入 | 不能 | 被篡改的页面可以读取你选中的任何文件,所以要确认是正确域名的 HTTPS |
| 恶意浏览器扩展 | 不能 | 扩展可以读取页面内容,装的扩展越多风险越大 |
| 共享或不受信任的电脑 | 不能 | 文件可能留在下载文件夹、浏览器缓存或系统缩略图中 |
| 用户自己把结果发给别人 | 不能 | 本地处理只保证处理过程,不管你之后怎么分享 |
六、真实的资源限制
浏览器标签页没有服务器那样的算力和内存,所以好的本地工具会明确设置上限,而不是让页面卡死。以下数字来自 ToolGarden 源码:
| 场景 | 限制 |
|---|---|
| 图片转换、去水印、加水印等 | 单个文件不超过 50MB,像素不超过 4000 万 |
| 二维码识别 | 单个图片不超过 12MB,像素不超过 2400 万 |
| AI 图片放大、图像增强 | 源图像素不超过 400 万 |
| 二维码 logo | 不超过 4MB,像素不超过 400 万 |
| 音频分轨模型 | 模型文件较大,Service Worker 的注释中提到约 130MB 的独立缓存 |
遇到限制提示时,不要当成工具坏了:先缩小图片再处理,或者分批处理,避免一次把整个文件夹拖进去。
七、离线能力到底到什么程度
站点注册了 Service Worker 和 Web App Manifest,因此可以安装为 PWA。它的缓存策略是:构建产物(/_next/static/)优先读缓存,页面路径优先走网络、网络失败时回退到缓存,其它 GET 请求同样先网络后缓存。这意味着:你访问过的页面和用到的静态资源,断网后一般还能打开;但是没有访问过的工具、没有下载过的模型,离线时不会凭空出现。想要离线使用某个工具,正确做法是联网时先打开它并跑一次完整流程。
八、什么时候不该用浏览器本地处理
- 需要审计留痕的合规场景:如果制度要求处理过程有可追溯的服务器日志,本地处理反而缺乏记录。
- 多 GB 级文件或长时间批处理:浏览器内存和单标签页算力有限,桌面软件或受控的服务端更合适。
- 复杂的 Office 排版保真:把版式复杂的文档在浏览器里转格式,往往没有专业桌面软件可靠。
- 多人协作、需要共享状态:本地处理天然是单机的。
- 设备本身不可信:在网吧或他人电脑上,本地处理的隐私优势会被设备风险抵消。
选择工具时的检查清单
- 用样本文件和 Network 面板验证一次,确认没有携带文件内容的上传请求。
- 确认输出格式保留了你需要的细节(例如透明度、字体、元数据)。
- 大批量处理之前,先看工具说明的文件大小和浏览器兼容性限制。
- 涉及敏感文件时,用隐私窗口,关闭不必要的扩展,处理完清理下载目录。