You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移动端Safari使用mozilla/pdfjs无法渲染内嵌PDF求助

在Rails 7.0.4 + Vite 3.1.3环境下,pdfjs-dist在iPhone Safari移动端无法渲染PDF(桌面端正常)

问题描述

使用mozilla/pdfjs实现内嵌PDF浏览,桌面端全浏览器兼容正常,但iPhone 11的Safari浏览器中无任何内容显示。已通过控制器处理worker文件的MIME类型冲突(路径/documents/pdfjs_worker),但移动端仍无渲染结果。

相关代码

View代码

<canvas id="the-canvas"></canvas>

JavaScript代码

// NPM
import * as pdfjsLib from 'pdfjs-dist/build/pdf'

window.showMozillaPdf = function () {
    var pdfData = atob(gon.doc_b64);
    
    console.log(pdfjsLib)
    pdfjsLib.GlobalWorkerOptions.workerSrc = '/documents/pdfjs_worker';

    console.log('pdf-part-2!')

    var loadingTask = pdfjsLib.getDocument({data: pdfData});
    loadingTask.promise.then(function (pdf) {
        console.log('PDF loaded');

        // Fetch the first page
        var pageNumber = 1;
        pdf.getPage(pageNumber).then(function (page) {
            console.log('Page loaded');

            var scale = 1.5;
            var viewport = page.getViewport({scale: scale});

            // Prepare canvas using PDF page dimensions
            var canvas = document.getElementById('the-canvas');
            var context = canvas.getContext('2d');
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            // Render PDF page into canvas context
            var renderContext = {
                canvasContext: context,
                viewport: viewport
            };
            var renderTask = page.render(renderContext);
            renderTask.promise.then(function () {
                console.log('Page rendered');
            });
        });
    }, function (reason) {
        // PDF loading error
        console.error(reason);
    });
}

解决步骤

  • 检查Safari控制台错误
    连接iPhone到Mac,通过Safari开发者工具查看控制台日志,排查是否存在worker加载失败、canvas权限、base64解码异常等问题。移动端Safari对API的限制与桌面端存在差异,错误日志是定位问题的关键。

  • 替换atob为兼容的解码方式
    Safari移动端对atob处理Unicode字符支持有限,改用Uint8Array解码:

    // 替换原有的var pdfData = atob(gon.doc_b64);
    var binaryString = window.atob(gon.doc_b64);
    var len = binaryString.length;
    var pdfData = new Uint8Array(len);
    for (var i = 0; i < len; i++) {
        pdfData[i] = binaryString.charCodeAt(i);
    }
    
  • 确保worker文件的MIME类型正确
    Rails控制器返回worker文件时,显式设置MIME类型为application/javascript:

    def pdfjs_worker
      worker_path = Rails.root.join('node_modules', 'pdfjs-dist', 'build', 'pdf.worker.js')
      send_file worker_path, type: 'application/javascript', disposition: 'inline'
    end
    
  • 添加canvas兼容性样式与适配
    给canvas添加样式避免布局异常,同时适配移动端屏幕像素比:

    #the-canvas {
      display: block;
      max-width: 100%;
      height: auto;
    }
    

    调整渲染代码中的缩放逻辑:

    var scale = window.devicePixelRatio || 1.5;
    var viewport = page.getViewport({scale: scale});
    
    canvas.height = viewport.height * scale;
    canvas.width = viewport.width * scale;
    canvas.style.height = viewport.height + 'px';
    canvas.style.width = viewport.width + 'px';
    
    context.scale(scale, scale);
    
    var renderContext = {
        canvasContext: context,
        viewport: viewport
    };
    
  • 调整Vite配置适配pdfjs
    尝试导入UMD版本的pdfjs,或在Vite配置中添加优化规则:

    // 导入UMD版本
    import * as pdfjsLib from 'pdfjs-dist/build/pdf.umd'
    
    // vite.config.js
    export default {
      optimizeDeps: {
        include: ['pdfjs-dist']
      }
    }
    

内容的提问来源于stack exchange,提问作者chmich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:45:38