
凌晨十一点半,法务发来三个扫描件:合同正文、签章页、补充协议,要你明早合并成一个 PDF 归档。你随手搜“pdf 合并”,排第一的在线工具进度条走完那一刻,突然后背发凉——这是一份没披露的收购合同,刚在某个来路不明的小站服务器上走了一遭。
被坑惨了才知道疼。这篇就聊聊:怎么让 PDF 合并这件事,文件一个字节都不出你的浏览器。
在线工具的隐性成本:文件即筹码。 免费合并的站,变现路径无非广告、会员、或数据。前两个无所谓,第三个你敢赌吗?
说人话:文件一旦上传,控制权就没了。服务器的访问日志、临时目录、CDN 缓存、自动备份,任何一个环节留了副本,“用后即删”就是一句空话。
有隐私政策就安全了?不。政策是承诺,不是技术隔离。承诺这种东西,出事的时候才发现一个字都不顶用。
先说结论:整个过程拆开就四步,没有一步碰网络。
解析:浏览器的 FileReader 把文件读成 ArrayBuffer,pdf-lib 拿到字节流后解析交叉引用表,还原出 PDF 的对象树。
复制页对象:copyPages 不是截图重排,而是把源 PDF 的页面对象、字体、图片流整体深拷贝进新文档。这也是合并无损的根本原因。
拼接:addPage 按你定的顺序,把拷来的页挂到新文档的页树上,仅此而已。
序列化:save() 重新计算每个对象的字节偏移,生成新的 xref 表,输出 Uint8Array,剩下的交给 Blob 和下载。
怎么验证它没偷偷上传?打开 F12 → Network 挂着不关,跑一遍合并,请求数是 0 就是 0。别赌运气,亲手看一次,比读一百句“我们不上传”都管用。
硬伤所在:pdf-lib 根本不实现解密。 PDF 加密不是“锁个门”那么简单,密码要通过固定算法推导出密钥,再对每个对象流做 AES/RC4 解密,这套逻辑 pdf-lib 压根没写。
所以你扔一个带密码的 PDF 进去,得到的不是“请输入密码”的弹窗,而是冷冰冰的 EncryptedPDFError。为什么不做个密码输入框?做了就是解密工具,合规风险直接换一个量级。
那加密文件怎么办?两条路:有密码,先在本地另存一份解密版再合并;没密码,别折腾了,浏览器端方案帮不了你。
PDF 合并看着是 IO 活,其实是内存活。所有源文件的完整字节流都得进内存,序列化时新旧对象还要并存。
峰值出现在 save()。 生成输出的同时,输入的 ArrayBuffer 还没释放,1GB 输入峰值吃掉 3GB 内存很正常。手机浏览器合并大扫描件白屏 reload,基本都死在这一步。
为什么不能流式处理?xref 表是格式级硬伤。 PDF 规范要求每个对象在文件里的字节偏移精确可查,天生不适合边读边写。这是 1993 年定下的规矩,不是哪个库偷懒。
工程上的权衡就三条:超大文件提示用户分批合并;扫描件先压缩再合并;真到几个 G 的量级,老老实实换桌面工具,别为难一个浏览器 tab。
最狠的测试:断网,再跑一遍。真本地工具断网照样能合并,假本地当场原形毕露。
其次盯着 Network 面板,上传请求藏不住。再看技术实现,用 pdf-lib、pdfjs-dist 这类库的基本稳,纯表单扔给后端处理的,趁早关页面——踩过一次坑你就不想踩第二次。
想省掉验证步骤,直接试本站的 PDF 合并:pdf-lib 的浏览器端方案,文件不进服务器,断网也能合,合完即走,你那份没披露的合同可以睡个安稳觉。
本地合并会掉画质、丢内容吗? 不会掉画质,拷贝的是原始对象流,无损。但部分实现会丢表单域和书签,重要文件合并后记得翻一遍页数和目录。
几百页的扫描件能合吗? 看单页体积。每页 5MB、一百页就是 500MB,峰值内存轻松破 1.5GB,电脑问题不大,手机上别赌运气。
免费又不上传,这种工具图什么? 浏览器端方案没有服务器带宽和存储成本,静态托管开销趋近于零。没有你的文件可图,这才是能长期免费的原因。
评论列表 (0条)