如何解决pdf.js跨域从url动态加载pdf文档

摘要

当我们想用PDF.js从URL加载文档时,将会因遇到跨域问题而中断,且是因为会触发了PDF.js和浏览器的双重CORS block,这篇文章将会介绍:①如何禁用pdf.js的跨域?②如何绕过浏览器的CORS加载URL文件?②如何使用PDF.js动态加载URL文件?

关键词 : PDF.js , CORS , URL , 动态加载

1. Demo和源码

Demo和源码:https://demos.libertynlp.com/#/pdfjs-cors

源码是我已经完成所有设置的 PDF.js 代码,下载后导入你的项目中即可从 url 动态加载pdf。

2. 解决PDF.js跨域

要彻底解决 PDF.js 的跨域问题,让 PDF.js 可以从 url 加载文档,需要解决 PDF.js 本身和浏览器的双重跨域问题。

2.1 禁用PDF.js跨域

要禁用 PDF.js CORS,需要在 viewer.js 文档中将下面一段代码注释掉,让它失效。

复制代码
// 原代码
      if (origin !== viewerOrigin && protocol !== "blob:") {
        throw new Error("file origin does not match viewer's");
      }

// 注释掉上方代码
      // if (origin !== viewerOrigin && protocol !== "blob:") {
      //   throw new Error("file origin does not match viewer's");
      // }
2.2 绕过浏览器跨域

要解决浏览器 URL 文件跨域的问题,可以通过后端服务器将PDF 文件转换成流文件的方式返回给 PDF.js ,不过这里我们不讨论这样的策略,而是讨论如何只在前端解决这个问题。按照以下步骤可以解决问题。

  1. viewer.js 中注释掉以下三处代码,然后重写加载 PDF 文件的函数 webViewerLoadRun函数。

    // inactivate follow original code in viewer.js

    //first place
    function webViewerLoad() {
    var config = getViewerConfiguration();
    window.PDFViewerApplication = pdfjsWebApp.PDFViewerApplication;
    window.PDFViewerApplicationOptions = pdfjsWebAppOptions.AppOptions;
    var event = document.createEvent("CustomEvent");
    event.initCustomEvent("webviewerloaded", true, true, {});
    document.dispatchEvent(event);
    pdfjsWebApp.PDFViewerApplication.run(config);
    }

    //second place
    if (document.readyState === "interactive" || document.readyState === "complete") {
    webViewerLoad();
    } else {
    document.addEventListener("DOMContentLoaded", webViewerLoad, true);
    }

    //third place
    run: function run(config) {
    this.initialize(config).then(webViewerInitialized);
    },

  2. 重写 webViewerLoad 和 Run 函数

    // 重写 webViewerLoad 函数
    window.webViewerLoad = function webViewerLoad(fileUrl) {
    var config = getViewerConfiguration();
    window.PDFViewerApplication = pdfjsWebApp.PDFViewerApplication;
    window.PDFViewerApplicationOptions = pdfjsWebAppOptions.AppOptions;
    var event = document.createEvent('CustomEvent');
    event.initCustomEvent('webviewerloaded', true, true, {});
    document.dispatchEvent(event);

    复制代码
     if (fileUrl) {
         config.defaultUrl = fileUrl;
     }
     pdfjsWebApp.PDFViewerApplication.run(config);

    }

    //rewrite run function
    //modeify for browser CORS
    run: function run(config) {
    var _that = this;
    //add judgement
    if (config.defaultUrl) {
    _app_options.AppOptions.set('defaultUrl', config.defaultUrl)
    }

    复制代码
     _that.initialize(config).then(function() {
         webViewerInitialized()
     });

    },

2.2.2 调用以上修改

viewer.html 中新增一个函数,目的是在加载页面时调用修改过的 webViewerLoad 函数。

复制代码
< script type = "text/javascript" >
    window.onload = function() {
        var pdfUrl = "https://heritagesciencejournal.springeropen.com/track/pdf/10.1186/s40494-021-00620-2.pdf";
        webViewerLoad(pdfUrl);
    }
</script>

3. 从URL动态加载PDF

修改 viewer.html 中的函数,根据 viewer.html 所在 iframe 标签 src 中携带的 PDF url 加载文件。

复制代码
<script type = "text/javascript" >
    window.onload = function() {
        var all_href = location.href;
        var file_id = all_href.split('?')[1];
        var pdfUrl = file_id.split('=')[1];
        // var pdfUrl='https://fireflycos.libertynlp.com/firefly-static/new_shouce.pdf';
        webViewerLoad(pdfUrl);
    }
</script>

当在项目中使用 iframe 引用 PDF.jsviewer.html 时,只需要修改 *src="viewer.html?file=" *后面的 PDF Url 地址就可以了。也就是改变 <iframe> 的 src 属性值就可以实现动态加载PDF文档。

复制代码
//complete test.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body data-rsssl=1 data-rsssl=1>
        <iframe loading="lazy" id="pdf_container" src="viewer.html?file=https://fireflycos.libertynlp.com/firefly-static/new_shouce.pdf"
        frameborder="0" width="100%" height="800px"></iframe>
    </body>
</html>

4. 总结

想要 PDF.js 通过 URL 加载文件,需要修改以下几个地方。如果想看看效果或者直接使用我已经修改好的版本,可以到Demo和源码网址:https://demos.libertynlp.com/#/pdfjs-cors

复制代码
1.在viewer.js中停用跨域判断代码
2.重构viewer.js中 webViewerLoader和run函数来解除浏览器的CORS限制
3.在iframe标签的src属性中增加file参数,实现PDF文件的动态加载
相关推荐
anOnion6 小时前
Agentic 前端开发之 实时显示 AI Agent 终端输出
前端·javascript·人工智能
这是个栗子6 小时前
【前端性能优化】优化数据加载:用 Promise.all 从串行到并行
前端·javascript·性能优化·异步编程·前端优化·promise.all
wenxin77wx6 小时前
3步部署OlmOCR:一行命令将PDF转为LLM训练数据
pdf·- olmocr
fei_sun6 小时前
黑洞路由(Null Route/空接口路由)
服务器·前端·javascript
摇滚侠8 小时前
方法 A 等方法 B 执行完再执行 叫同步调用还是异步调用 JS 默认是同步调用还是异步调用
开发语言·javascript·ecmascript
触底反弹8 小时前
🔥 字符串算法面试三连击:反转、回文、回文变种,搞懂这三题稳了!
前端·javascript·算法
触底反弹9 小时前
AI Tool Use 深度解析:大模型是如何"突破物理限制"调用外部工具的?
javascript·人工智能·后端
竹林8189 小时前
从 RPC 超时到批量签名:我用 @solana/web3.js 重构了一个 NFT 铸造页面,踩了这些坑
前端·javascript
ShiXZ2139 小时前
PDF-OCR文件识别篇(七):数据入库
java·pdf·json·ocr·springboot
优雅格子衫9 小时前
TypeScript 类的基本使用小结
javascript·ubuntu·typescript