0

Client-side PDF processing: Xử lý file PDF ngay trên trình duyệt, không cần upload lên server

Vấn đề: đa số công cụ PDF online đều bắt bạn upload file lên server

Khi cần chuyển PDF sang Word, gộp, tách hay nén file, thói quen của rất nhiều người là tìm một công cụ online, kéo file vào và chờ kết quả trả về. Điều ít ai để ý: trong khoảnh khắc đó, file của bạn đã được tải lên máy chủ của một bên thứ ba.

Với tài liệu bình thường thì không có gì đáng ngại. Nhưng với CCCD, hợp đồng lao động, hóa đơn, hồ sơ bệnh án hay bảng lương — những thứ chứa dữ liệu cá nhân — đây là một rủi ro có thật. Đặc biệt từ khi Luật Bảo vệ dữ liệu cá nhân 91/2025/QH15 và Nghị định 356/2025/NĐ-CP có hiệu lực tại Việt Nam, câu chuyện "file đi đâu sau khi upload" không còn là chuyện nhỏ.

Giải pháp: xử lý ngay trên trình duyệt (client-side)

Tin vui là nhờ WebAssembly, rất nhiều thao tác PDF trước đây bắt buộc phải chạy trên server thì nay có thể chạy hoàn toàn bên trong tab trình duyệt:

  • pdf-lib (JavaScript thuần): gộp, tách, xoay trang, sắp xếp lại trang, đánh số trang, đọc/ghi metadata
  • pdf.js (Mozilla): render PDF ra canvas, từ đó xuất sang ảnh JPG/PNG
  • qpdf-wasm / gs-wasm: nén, mã hóa, giải mã
  • tesseract.js: OCR chạy ngay trên browser

Nguyên lý rất đơn giản: file được đọc bằng FileReader hoặc ArrayBuffer, xử lý trong bộ nhớ của trình duyệt, rồi tạo Blob kết hợp URL.createObjectURL() để người dùng tải xuống. File không bao giờ rời khỏi thiết bị.

import { PDFDocument } from 'pdf-lib';

async function mergePdfs(files) {
  const merged = await PDFDocument.create();

  for (const file of files) {
    const bytes = await file.arrayBuffer();
    const pdf = await PDFDocument.load(bytes);
    const pages = await merged.copyPages(pdf, pdf.getPageIndices());
    pages.forEach((page) => merged.addPage(page));
  }

  const out = await merged.save();
  const blob = new Blob([out], { type: 'application/pdf' });
  const url = URL.createObjectURL(blob);
  // nhớ revoke sau khi dùng xong
  return url;
}

Khi nào client-side chưa đủ?

Thành thật mà nói, không phải thứ gì cũng làm tốt được trên trình duyệt. Đây là bức tranh thực tế:

Thao tác Client-side làm tốt? Ghi chú
Gộp / tách / xoay / sắp xếp trang Có, hoàn toàn pdf-lib xử lý rất ổn
Đọc & xóa metadata Rất nhẹ
Thêm hình mờ, đánh số trang, ký Kết hợp canvas
Nén Tuỳ mức Nén sâu cần ghostscript wasm, khá chậm
Chuyển PDF sang Word giữ nguyên layout Khó Bài toán tái tạo cấu trúc vẫn rất nan giải
OCR tiếng Việt Có nhưng cần tinh chỉnh Cần model tiếng Việt, độ chính xác phụ thuộc ảnh đầu vào
File rất lớn (trên 200MB) Không Bộ nhớ trình duyệt có giới hạn

Một số lưu ý khi tự triển khai

  1. Đừng dùng readAsDataURL cho file lớn — hãy dùng ArrayBuffer, tiết kiệm bộ nhớ đáng kể.
  2. Nhớ giải phóng object URL: gọi URL.revokeObjectURL(url) sau khi người dùng tải xong.
  3. Đưa tác vụ nặng vào Web Worker: OCR và nén nên chạy trong worker để không làm đơ giao diện.
  4. Thành thật về giới hạn của mình: nếu có tính năng bắt buộc phải gửi lên server (ví dụ OCR nâng cao), hãy nói rõ cho người dùng, dùng kết nối mã hóa và cam kết không lưu trữ. Người dùng đánh giá cao sự trung thực hơn là một lời hứa mơ hồ.

Góc nhìn thực tế tại Việt Nam

Mình là người xây dựng CHUYENPDF.VN — một bộ công cụ PDF hoàn toàn bằng tiếng Việt với 18 công cụ. Trong đó 17/18 công cụ xử lý hoàn toàn client-side, file không rời khỏi thiết bị. Riêng OCR là ngoại lệ: ảnh được gửi qua kết nối mã hóa, không lưu trên máy chủ, và kết quả nhận dạng chỉ nằm trong bộ nhớ đệm tạm thời tối đa 5 phút rồi hết hạn.

Lý do chọn cách này không chỉ là kỹ thuật, mà còn vì bối cảnh pháp lý: khi người Việt xử lý CCCD, hồ sơ thuế, hồ sơ hộ chiếu hay hợp đồng, việc "file không rời khỏi máy" là một cam kết có giá trị thực, chứ không phải một câu slogan marketing.

Kết luận

Client-side PDF processing không thể thay thế server trong mọi trường hợp, nhưng với đa số nhu cầu hàng ngày — gộp, tách, nén, xoay, khóa, ký, xuất ảnh, xem metadata — nó nhanh hơn, riêng tư hơn, và không tốn chi phí hạ tầng.

Nếu bạn đang xây dựng một công cụ xử lý tài liệu cho người dùng Việt Nam, mình nghĩ đây là hướng đáng để cân nhắc nghiêm túc: vừa giải được bài toán kỹ thuật, vừa đáp ứng đúng tinh thần của các quy định bảo vệ dữ liệu cá nhân hiện hành.

Bạn đang xử lý PDF theo cách nào? Nếu có kinh nghiệm gì hay về pdf-lib hay WebAssembly, chia sẻ ở phần bình luận nhé.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.