Technical

Chỉnh Sửa PDF Trực Tiếp Trên Trình Duyệt: Nguyên Lý Hoạt Động & Bảo Mật

Cách LuraPDF xử lý PDF hoàn toàn trong trình duyệt bằng pdf-lib, pdfjs-dist, Tesseract.js và WebAssembly, nên tệp của bạn không bao giờ bị tải lên.

LuraPDF Team
LuraPDF Team

Nhóm Biên tập & Kỹ thuật · 6 tháng 5, 2026 · 12 phút đọc

Mỗi khi bạn tải một tài liệu lên công cụ PDF dựa trên đám mây, tài liệu đó tồn tại trên các máy chủ mà bạn không kiểm soát, được xử lý bởi phần mềm bạn không thể kiểm tra, và được lưu trữ bởi một công ty với chính sách lưu giữ dữ liệu và bảo mật riêng của họ. Trong một khoảng thời gian ngắn, cơ sở hạ tầng của người khác nắm giữ hợp đồng, hồ sơ thuế, hồ sơ y tế, hoặc tài liệu kinh doanh bảo mật của bạn.

LuraPDF hoạt động khác biệt. Mọi thứ diễn ra trong tab trình duyệt của bạn, trên phần cứng của bạn, với bộ quản lý bộ nhớ của hệ điều hành bạn đang dùng. Bài viết này giải thích kiến trúc kỹ thuật làm cho điều này trở nên khả thi và những đánh đổi kỹ thuật liên quan.

Trình Duyệt Như Một Nền Tảng Xử Lý Tài Liệu

Các trình duyệt hiện đại không còn chỉ là bộ kết xuất HTML. Chúng là môi trường thực thi ứng dụng đầy đủ tính năng với:

  • JavaScript engine (V8 trong Chrome, SpiderMonkey trong Firefox): thực thi mã ở tốc độ gần bằng native
  • WebAssembly (WASM): thực thi mã C/C++ đã biên dịch ở tốc độ gần bằng native trong môi trường sandbox
  • Canvas API: cho phép thao tác hình ảnh ở cấp độ pixel
  • File System Access API: cho phép đọc tệp cục bộ mà không cần tải lên
  • Web Workers: chạy tính toán trên luồng nền mà không làm đóng băng giao diện người dùng
  • ArrayBuffer / Blob: quản lý dữ liệu nhị phân thô (như byte PDF) trong bộ nhớ

Các khả năng này kết hợp với nhau tạo nên một pipeline xử lý tài liệu đầy đủ tính năng — thứ mà năm năm trước đây đòi hỏi phải có máy chủ backend.

Ba Thư Viện Cốt Lõi

LuraPDF được xây dựng trên ba thư viện mã nguồn mở nền tảng:

pdf-lib

pdf-lib là một thư viện TypeScript để tạo và chỉnh sửa tài liệu PDF trong bất kỳ môi trường JavaScript nào. Nó triển khai một phần đáng kể của đặc tả PDF (ISO 32000), bao gồm:

  • Tạo, chỉnh sửa và xóa trang
  • Nhúng font (cả 14 font chuẩn và font TTF/OTF tùy chỉnh)
  • Nhúng hình ảnh (JPEG, PNG)
  • Đặt chú thích văn bản
  • Tạo và thao tác trường biểu mẫu
  • Siêu dữ liệu tài liệu (tiêu đề, tác giả, ngày tạo, v.v.)
  • Bảo vệ tài liệu bằng mật khẩu
  • Quản lý bảng tham chiếu chéo

Khi LuraPDF gộp các PDF, nó dùng pdf-lib để đọc cây trang của mỗi tài liệu, chuẩn hóa các tài nguyên chung, và lắp ráp một PDF mới. Khi nén, nó mã hóa lại các đối tượng hình ảnh với hệ số chất lượng thấp hơn. Khi bảo vệ tệp bằng mật khẩu, nó dẫn xuất khóa từ mật khẩu của bạn và ghi một tài liệu được mã hóa bằng PDF Standard Security Handler — thứ mà mọi trình đọc đều hiểu.

pdf-lib hoạt động hoàn toàn trên các đối tượng ArrayBuffer — dữ liệu nhị phân thô trong bộ nhớ trình duyệt. Không có lệnh gọi mạng nào được thực hiện.

pdfjs-dist

PDF.js là engine kết xuất PDF của Mozilla, được phân phối dưới dạng pdfjs-dist trên npm. Đây là engine cung cấp sức mạnh cho trình xem PDF tích hợp của Firefox, đã được kiểm thử với hàng triệu tệp PDF thực tế.

LuraPDF sử dụng pdfjs-dist cho:

  • Kết xuất trang: Chuyển đổi các trang PDF thành Canvas ImageData để hiển thị
  • Trích xuất văn bản: Đọc các luồng nội dung văn bản từ các trang PDF
  • Siêu dữ liệu trang: Lấy kích thước trang, giá trị xoay và loại nội dung

Khi bạn thấy PDF của mình được kết xuất trong giao diện LuraPDF — bản xem trước trực quan của các trang — đó là pdfjs-dist đang kết xuất từng trang lên một phần tử HTML Canvas.

Tesseract.js

Tesseract.js là phiên bản biên dịch WebAssembly của Tesseract OCR. Tesseract là một engine OCR mã nguồn mở ban đầu được phát triển bởi HP Labs (1985) và hiện được Google duy trì. Nó sử dụng mô hình mạng nơ-ron LSTM (Long Short-Term Memory) để nhận dạng ký tự.

Chạy Tesseract qua WebAssembly trong trình duyệt có nghĩa là:

  • File nhị phân WASM 22 MB được tải một lần và được trình duyệt cache lại
  • Xử lý OCR chạy trên CPU qua WebAssembly, không phải GPU
  • Xử lý chậm hơn OCR đám mây (sử dụng cụm GPU) nhưng cho ra cùng chất lượng đầu ra
  • Nội dung tài liệu của bạn không bao giờ rời khỏi thiết bị

Với một bản scan 20 trang: OCR trình duyệt mất khoảng 30–120 giây. Một dịch vụ đám mây có thể mất 2–5 giây. Sự đánh đổi là quyền riêng tư so với tốc độ.

Kiến Trúc: Từ Tệp Đến Đầu Ra

Đây là những gì xảy ra khi bạn, ví dụ, nén một PDF trong LuraPDF:

  1. Chọn tệp: Bạn kéo một PDF vào vùng thả. File API của trình duyệt đọc tệp vào một ArrayBuffer — byte thô trong bộ nhớ trình duyệt. Không có lần tải lên nào xảy ra.

  2. Xác thực: Kiểm tra nhanh rằng các byte ma thuật %PDF xuất hiện ở đầu ArrayBuffer.

  3. Tải: PDFDocument.load() của pdf-lib phân tích bảng tham chiếu chéo, đọc cây đối tượng, và xây dựng một biểu diễn trong bộ nhớ của tài liệu.

  4. Liệt kê hình ảnh: Thư viện duyệt qua các luồng nội dung trang để tìm các XObject hình ảnh (hình ảnh được nhúng). Chiều rộng, chiều cao, kiểu nén và dữ liệu byte của mỗi hình ảnh được trích xuất.

  5. Mã hóa lại: Với mỗi hình ảnh, dữ liệu pixel thô được vẽ lên một phần tử HTML Canvas, sau đó được xuất lại ở hệ số chất lượng JPEG thấp hơn bằng canvas.toBlob('image/jpeg', quality). Đối tượng hình ảnh gốc được thay thế bằng phiên bản đã mã hóa nhỏ hơn.

  6. Tuần tự hóa tài liệu: Phương thức save() của pdf-lib tuần tự hóa tài liệu đã chỉnh sửa trở lại thành byte. Các luồng đối tượng được nén DEFLATE.

  7. Tải xuống: Các byte được bọc trong một đối tượng Blob, một URL đối tượng tạm thời được tạo (URL.createObjectURL(blob)), và một lần nhấp <a> theo chương trình kích hoạt cơ chế tải xuống của trình duyệt.

Tổng dữ liệu được truyền đến bất kỳ máy chủ bên ngoài nào: không byte nào.

Web Workers: Giữ Cho Giao Diện Phản Hồi

Xử lý PDF là tác vụ tốn CPU. Chạy nó trên luồng JavaScript chính sẽ đóng băng tab trình duyệt — bạn không thể cuộn, nhấp, hoặc xem cập nhật tiến trình trong khi tệp đang được xử lý.

LuraPDF chạy tất cả các tính toán nặng (OCR, phân tích PDF lớn, mã hóa lại hình ảnh) trong Web Workers — các luồng JavaScript riêng biệt chạy nền. Luồng chính xử lý giao diện người dùng, hiển thị thanh tiến trình, và giao tiếp với worker qua truyền thông điệp (postMessage / onmessage).

Khi OCR đang chạy, một sự kiện tiến trình được kích hoạt sau khi mỗi trang được xử lý. Worker gửi { page: 5, total: 20, confidence: 94 } đến luồng chính, thứ cập nhật thanh tiến trình. Giao diện người dùng của bạn vẫn tương tác trong suốt quá trình.

Quản Lý Bộ Nhớ

Bộ nhớ trình duyệt là hữu hạn. Một PDF 200 MB được tải vào bộ nhớ, xử lý, và lưu có thể cần 400–600 MB RAM (byte gốc + dữ liệu Canvas trung gian + byte đầu ra). Trên các hệ thống có RAM hạn chế, điều này có thể gây áp lực bộ nhớ.

Các chiến lược được sử dụng:

  • Xử lý trang theo luồng: Với các tác vụ nhiều trang, các trang được xử lý và các phần tử Canvas trung gian được loại bỏ sau khi sử dụng
  • URL.revokeObjectURL(): Các URL blob tạm thời được thu hồi sau khi tải xuống để cho phép GC
  • Chấm dứt Worker: Web Workers bị chấm dứt sau khi hoàn thành tác vụ để thu hồi bộ nhớ họ đã sử dụng

Với các tệp rất lớn (>100 MB), các trình duyệt hiện đại xử lý điều này mà không gặp vấn đề trên các hệ thống có 8+ GB RAM. Các hệ thống cũ hơn hoặc bị hạn chế bộ nhớ có thể gặp khó khăn với các tệp nguồn 100+ MB.

Kiến Trúc Quyền Riêng Tư

Mô hình bảo mật được thực thi bởi chính sách cùng nguồn gốc và kiến trúc cô lập của trình duyệt:

  • Không có HTTP request: Không có lệnh gọi API bên ngoài, không có telemetry, không có lệnh gọi analytics trong quá trình xử lý tài liệu
  • Thực thi trong sandbox: Web Workers không thể thực hiện lệnh gọi mạng đến các nguồn gốc bên ngoài
  • Không lưu trữ liên tục: Các tệp đã xử lý không được ghi vào bộ nhớ trình duyệt (localStorage, IndexedDB, hoặc File System Access)
  • Bộ nhớ phạm vi tab: Khi bạn đóng tab, tất cả ArrayBuffer và đối tượng Blob liên quan đến nó đều được thu gom rác

Kiến trúc này có thể xác minh được: mở tab Mạng trong DevTools của trình duyệt trong khi xử lý tệp. Bạn sẽ thấy không có request nào trong suốt quá trình xử lý.

Thư Viện Mã Nguồn Mở: Có Thể Kiểm Tra, Không Phải Hộp Đen

Cả ba thư viện cốt lõi — pdf-lib, pdfjs-dist và Tesseract.js — đều là mã nguồn mở với kho lưu trữ công khai trên GitHub. Các triển khai có thể được kiểm tra bởi bất kỳ ai. Mã xử lý PDF chạy trong LuraPDF không phải là hộp đen độc quyền; đó là mã công khai với người dùng thực, vấn đề và đóng góp thực sự.

Điều này quan trọng cho sự tin tưởng. Khi một dịch vụ đám mây nói "chúng tôi xử lý và xóa tệp của bạn," bạn đang tin vào lời họ nói. Khi LuraPDF sử dụng các thư viện mã nguồn mở trong sandbox trình duyệt không có lệnh gọi mạng, bạn có thể xác minh tuyên bố bằng cách theo dõi tab mạng.

Đánh Đổi So Với Xử Lý Đám Mây

Mô hình dựa trên trình duyệt có những đánh đổi thực sự đáng được thẳng thắn nói về:

Tốc độ: Các dịch vụ đám mây có cụm GPU và cơ sở hạ tầng chuyên dụng. OCR trình duyệt trên một tài liệu lớn mất lâu hơn 2–10 lần so với đám mây tương đương. Nén thì nhanh vì nó sử dụng Canvas API trực tiếp.

Giới hạn kích thước tệp: Bộ nhớ trình duyệt là giới hạn. Các tệp rất lớn (>300 MB) có thể chạm giới hạn bộ nhớ trên một số hệ thống. Các dịch vụ đám mây không có ràng buộc như vậy.

Sức mạnh xử lý: WASM chạy ở 40–80% tốc độ C++ native. Các dịch vụ đám mây chạy mã native được tối ưu hóa. Với hầu hết tài liệu, sự khác biệt này không đáng kể; với các công việc OCR 100+ trang thì nó rõ ràng hơn.

Tính năng: Một số tính năng PDF nâng cao (kiểm tra tuân thủ PDF/X, quản lý màu chuyên nghiệp, quy trình làm việc CMYK) đòi hỏi các công cụ phía máy chủ chuyên biệt. Xử lý dựa trên trình duyệt xử lý được 95% trường hợp.

Với xử lý tài liệu hàng ngày — nén, gộp, ký, chuyển đổi, biên tập — mô hình dựa trên trình duyệt đủ nhanh, riêng tư theo thiết kế, và không yêu cầu tài khoản hay đăng ký.

Câu Hỏi Thường Gặp

LuraPDF có thu thập telemetry hay dữ liệu sử dụng không? LuraPDF sử dụng Google Analytics để thống kê lượt xem trang tổng hợp. Các thao tác xử lý tài liệu không tạo ra sự kiện analytics nào. Nội dung tệp của bạn không bao giờ được truyền đi.

Tôi có thể xác minh rằng không có lần tải lên nào xảy ra không? Có. Mở Developer Tools (F12), nhấp vào tab Mạng, lọc theo "XHR" hoặc "Fetch." Xử lý một tệp. Quan sát không có request mạng nào liên quan đến tài liệu trong quá trình xử lý.

Tại sao OCR mất nhiều thời gian hơn so với các dịch vụ khác? Tesseract.js dựa trên trình duyệt chạy trên CPU qua WebAssembly. Các dịch vụ OCR đám mây chạy trên cụm GPU xử lý ký tự nhanh hơn nhiều bậc độ lớn. Sự đánh đổi là tài liệu của bạn không bao giờ rời khỏi trình duyệt.

Điều gì xảy ra nếu tôi đóng tab trong khi đang xử lý? Xử lý dừng ngay lập tức. Bộ nhớ của tab trình duyệt được thu gom rác. Tệp gốc của bạn trên đĩa không thay đổi.

Mã có phải là mã nguồn mở không? Các thư viện xử lý cốt lõi (pdf-lib, pdfjs-dist, Tesseract.js) là mã nguồn mở. Mã giao diện của LuraPDF hiện chưa phải mã nguồn mở, nhưng pipeline xử lý chỉ sử dụng các thành phần mã nguồn mở.

Sự chuyển dịch sang xử lý tài liệu dựa trên trình duyệt không phải là một chiêu trò. Đó là một lựa chọn kiến trúc thực sự với những lợi thế riêng tư và tin cậy có thể đo lường được — với cái giá là tốc độ trên các tác vụ nặng. Với các tài liệu mà bạn muốn chúng không tồn tại trên máy chủ của người khác, đây là sự đánh đổi đúng đắn.

Về tác giả

LuraPDF Team
LuraPDF Team

Nhóm Biên tập & Kỹ thuật · 6 tháng 5, 2026 · 12 phút đọc

Đội ngũ LuraPDF là tập hợp các chuyên gia xử lý tài liệu, kỹ sư phần mềm và người viết tài liệu kỹ thuật, cùng nhau giúp việc chỉnh sửa PDF trở nên miễn phí, riêng tư và dễ tiếp cận với mọi người.