跳至內容
100% 本地 · 上傳 0 KB壓縮 PDF

客戶端 PDF 處理:瀏覽器本機 PDF 工具如何運作

客戶端 PDF 工具做與伺服器 相同的工作,但在使用者的瀏覽器中。這個 頁面面向想了解架構的開發者和 IT 管理員:涉及哪些 瀏覽器 API、哪些函式庫做 繁重工作、檔案實際去了哪裡,以及 誠實的限制是什麼。IXPDF 是進行中的範例,但 模型適用於任何瀏覽器本機 PDF 工具。

管線

從檔案輸入到下載,無需伺服器

客戶端 PDF 操作的端對端 流程是:

  1. 檔案輸入。使用者將檔案拖放進放置區。瀏覽器給頁面一個 File 物件(指向磁碟上檔案的指標,而非位元組本身)。
  2. 讀入記憶體。頁面呼叫 file.arrayBuffer() 將位元組讀入頁面記憶體中的 ArrayBuffer。這是檔案位元組存在於頁面中的唯一時刻;它們還不在 worker 中。
  3. 驗證。頁面在做任何事之前檢查檔案類型(magic bytes、副檔名)和大小。無效檔案在主執行緒上快速失敗,永遠不會到達 worker。
  4. 轉移至 Web Worker。頁面將 ArrayBuffer 發送給 worker,使用可轉移轉移讓位元組移動(無拷貝)到 worker 的堆積區。主執行緒不再存取緩衝區。
  5. 在 worker 中處理。worker 呼叫 PDF 函式庫(pdf-lib、PDF.js 或編譯為 WASM 的 qpdf/mupdf)來解析和修改 PDF。這是繁重工作,在主執行緒之外執行以免 UI 凍結。
  6. 回傳結果。worker 產生新的 ArrayBuffer(或 Blob)並回傳給主執行緒,同樣以可轉移方式。
  7. 提供下載。主執行緒將結果包進 Blob,呼叫 URL.createObjectURL(blob) 並透過 <a download> 元素提供下載。物件 URL 在下載開始後撤銷以避免記憶體洩漏。

在這個流程中,檔案在任何時候都不會離開 裝置。沒有 fetch、沒有XMLHttpRequest、沒有 包含檔案內容的 sendBeacon。頁面 進行的唯一網路請求是首次 載入頁面時的靜態資源(HTML、JS、CSS、字型)。

建構區塊

涉及的瀏覽器 API 和函式庫

客戶端 PDF 工具依賴一組小 瀏覽器 API 和一組小 JavaScript 函式庫。每個各司其職。

  • File API——File 和 Blob 介面。file.arrayBuffer() 將位元組讀入記憶體;new Blob([bytes], { type: 'application/pdf' }) 將位元組打包以下載。
  • Web Workers——有自己堆積區的背景執行緒,無法存取 DOM。PDF 解析在這裡執行讓主執行緒保持回應。通訊透過 postMessage;ArrayBuffer 可透過第二個引數轉移(移動,非拷貝)。
  • URL.createObjectURL / URL.revokeObjectURL——產生指向記憶體中結果的臨時 blob: URL,讓 <a download> 元素能提供下載。URL 必須撤銷否則會洩漏。
  • pdf-lib——純 JavaScript PDF 函式庫,可建立、修改和重新儲存 PDF。用於合併、分割、旋轉、浮水印、頁面操作和元資料編輯。不處理加密(已知限制——見下文)。
  • PDF.js——Mozilla 的 PDF 渲染器,用於將頁面渲染到 canvas(用於 PDF 轉影像)和解析 pdf-lib 無法讀取的 PDF。
  • WASM(可選)——用於將原生程式碼編譯為 WASM 在瀏覽器中以接近原生的速度執行的函式庫。qpdf 和 mupdf 可編譯為 WASM;IXPDF 對 pdf-lib 無法完成的操作選擇性地使用此路徑。
  • CompressionStream——瀏覽器原生的串流壓縮 API(gzip、deflate)。對某些大小縮減路徑有用,無需交付 JS 壓縮函式庫。

為什麼用 worker

為什麼 PDF 解析不在主執行緒上執行

PDF 解析是 CPU 密集且 同步的——讀位元組、解碼物件、跟隨 交叉引用、建構記憶體中的樹。50 MB 的 PDF 可能需要數百 毫秒解析,200 MB 的可能 需要數秒。如果這工作在 主執行緒上執行,頁面在整個 期間凍結:沒有動畫、沒有捲動、沒有輸入。 瀏覽器可能顯示「頁面無回應」對話框。

將工作移到 Web Worker 解決了這個問題。主 執行緒保持回應;worker 在背景處理 PDF; 頁面顯示進度指示器並在 worker 回傳 結果時更新 UI。代價是 worker 無法 存取 DOM,因此所有 UI 工作必須在 結果回傳後在主執行緒上進行。

worker 也有自己的記憶體預算。轉移給 worker 的大型 PDF 存在 worker 的 堆積區,而非頁面的。這對 非常大的檔案很重要:頁面可以保持輕量,而 worker 持有重型緩衝區,且緩衝區在 worker 完成時釋放。

可轉移物件

移動位元組,而非拷貝

當 ArrayBuffer 在不轉移的情況下發送給 worker 時,位元組被拷貝—— worker 得到自己的副本,主執行緒 保留原始。對 100 MB 的 PDF, 這意味使用了 200 MB 記憶體且有 可察覺的拷貝時間。

解決方案是轉移清單:postMessage 的第二個引數。將 緩衝區列入轉移清單會將 位元組移動到 worker——主執行緒的 引用被分離(長度為零),worker 取得 所有權。無拷貝、無記憶體倍增。回傳 結果時也用同樣的方法。

這是個小細節,但在規模上很重要。 沒有可轉移物件,大檔案的 客戶端 PDF 處理將不切實際。

誠實的限制

瀏覽器無法做好的事

客戶端處理不是銀彈。 有些操作在 瀏覽器中難以或無法做好,誠實的 工具會說出來而非偽造。

  • OCR。對掃描 PDF 進行光學字元辨識需要訓練好的模型和大量 CPU。瀏覽器 OCR 存在(Tesseract.js)但品質遠不如桌面 Tesseract 或雲端 OCR。IXPDF 將 OCR 標記為尚在研究。
  • PDF 加密(密碼保護)。pdf-lib 尚不支援寫入加密 PDF。新增需要另一個函式庫或編譯為 WASM 的 qpdf。IXPDF 的保護 PDF 工具尚在研究。
  • PDF 轉 Word/Excel/PowerPoint。將 PDF 轉換為可編輯的 Office 檔案是版面重建問題,需要後端。嘗試的瀏覽器函式庫產出低保真輸出。IXPDF 不提供這些轉換。
  • AI 摘要/問答。需要模型和後端。2026 年無法在客戶端以可接受的品質完成。IXPDF 不提供 AI 功能。
  • 非常大的檔案。瀏覽器分頁有記憶體預算(通常幾 GB)。2 GB 的 PDF 在大多數瀏覽器中會 OOM。伺服器端工具用串流處理;瀏覽器工具無法以同樣方式串流 PDF。

誠實的做法是在 UI 中將這些功能標記為Planned、Research Required 或Future Backend Candidate,而非 交付回傳空輸出並 假裝成功的假工具。這是本地優先工具和 內容農場「工具」頁面之間的界線。

為什麼重要

隱私屬性是結構性的,不是承諾

客戶端處理之所以是 重要的隱私屬性——而非只是 行銷說辭——是因為不上傳保證由程式碼的結構強制執行,而非由政策。沒有 可上傳的伺服器。頁面沒有 傳輸檔案內容的 fetch 呼叫。 使用者可以開啟 DevTools、進入 Network 分頁、 執行操作並驗證沒有 請求傳輸檔案。保證是 可稽核的。

這不同於一個承諾在 24 小時後刪除您檔案的伺服器端工具。那個承諾 由政策和您無法 看到的基礎設施強制執行。客戶端處理 由伺服器的不存在強制執行。對於 敏感檔案,這就是重要的差異。

更多資訊請見 IXPDF 隱私頁和關於 IXPDF。

接下來閱讀

相關資源