iOS 10.3.x中PDFJS首次渲染Base64 PDF出现乱码问题
Hey there, let's tackle this first-render garbled text issue with PDF.js on iOS 10.3.x—this is a super specific quirk I’ve helped debug before, and there are a few targeted fixes that should resolve it.
Common Causes & Fixes
1. Base64 Decoding Isn’t Fully Completed Before Rendering
iOS 10.3.x’s WebKit has a slight delay when processing synchronous Base64-to-Uint8Array conversions, which can leave incomplete data for the first PDF.js render.
Fix: Ensure your Base64 data is fully decoded before passing it to PDF.js. Here’s a reliable implementation:
function renderPdf(base64Data) { // Strip any data URI prefix if present const cleanedBase64 = base64Data.replace(/^data:application\/pdf;base64,/, ''); // Decode Base64 to Uint8Array (guarantees full data readiness) const uint8Array = new Uint8Array( atob(cleanedBase64).split('').map(char => char.charCodeAt(0)) ); // Initialize PDF.js only after data is ready pdfjsLib.getDocument({ data: uint8Array }).promise .then(pdf => pdf.getPage(1)) .then(page => { const viewport = page.getViewport({ scale: 1.2 }); const canvas = document.getElementById('pdf-render-canvas'); const ctx = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; // Render the page return page.render({ canvasContext: ctx, viewport }).promise; }) .catch(err => console.error('Render error:', err)); }
2. Blob URL Handling Delays on iOS 10.3.x
If you’re converting the Base64 data to a Blob URL before rendering, iOS 10.3.x’s WebKit often hasn’t finished processing the Blob by the time PDF.js tries to load it.
Fix: Skip the Blob URL entirely (use the Uint8Array method above), or add a tiny delay to give the Blob time to stabilize:
function renderPdfWithBlobFix(base64Data) { const cleanedBase64 = base64Data.replace(/^data:application\/pdf;base64,/, ''); const uint8Array = new Uint8Array( atob(cleanedBase64).split('').map(char => char.charCodeAt(0)) ); const blob = new Blob([uint8Array], { type: 'application/pdf' }); const blobUrl = URL.createObjectURL(blob); // 100ms delay ensures iOS WebKit finishes processing the Blob setTimeout(() => { pdfjsLib.getDocument(blobUrl).promise .then(pdf => pdf.getPage(1)) .then(page => { /* Render logic as above */ }); }, 100); }
3. PDF.js Font Caching Initialization Delay
iOS 10.3.x can struggle with PDF.js’s font loading on the first render, leading to missing or garbled text.
Fix: Pre-initialize PDF.js’s font cache before your first render:
// Run this once when your app loads pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.js'; // Ensure correct worker path // Trigger a dummy document load to initialize font processing pdfjsLib.getDocument({ data: new Uint8Array() }).promise.catch(() => { // This error is expected (empty document) — it just primes the font cache });
Quick Recap
The most reliable fix is to pass the decoded Uint8Array directly to PDF.js instead of using Blob URLs, and ensure your data is fully processed before starting the render. The font pre-initialization step adds an extra layer of protection for text rendering consistency.
内容的提问来源于stack exchange,提问作者Seth

