头图

【附源码】解决pdf.js跨域并从url动态加载pdf文档

0. Abstract

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

Keywords: PDF.js , CORS ,  URL , 动态加载 , demo , 源码。

1. Demo和源码

Demo和源码:https://demos.libertynlp.com/...

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

demo截屏.png

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 中注释掉以下三处代码

    // 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.3 调用以上修改

在 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.js 的 viewer.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/...

1.在viewer.js中停用跨域判断代码
2.重构viewer.js中 webViewerLoader和run函数来解除浏览器的CORS限制
3.在iframe标签的src属性中增加file参数,实现PDF文件的动态加载
2 声望
1 粉丝
0 条评论
推荐阅读
【附源码】web端pdf.js实现pdf批注注释编辑(写入保存/高亮/下划线/插入图片/矩形/箭头/圆形/文本/画笔)
基于pdf.js实现了 pdf 增加并编辑批注的 js 插件库,有高亮、下划线、插入图片、矩形、箭头、圆形、文本、画笔等工具,同时支持写入批注到pdf中并保存,为目前纯前端 javascript 最佳实现方案,仅使用了最新 PDF....

LibertyNLP阅读 247

封面图
从零搭建 Node.js 企业级 Web 服务器(零):静态服务
过去 5 年,我前后在菜鸟网络和蚂蚁金服做开发工作,一方面支撑业务团队开发各类业务系统,另一方面在自己的技术团队做基础技术建设。期间借着 Node.js 的锋芒做了不少 Web 系统,有的至今生气蓬勃、有的早已夭折...

乌柏木148阅读 12.1k评论 10

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy46阅读 5.8k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木65阅读 6k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs39阅读 6.3k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木42阅读 7.2k评论 6

从零搭建 Node.js 企业级 Web 服务器(二):校验
校验就是对输入条件的约束,避免无效的输入引起异常。Web 系统的用户输入主要为编辑与提交各类表单,一方面校验要做在编辑表单字段与提交的时候,另一方面接收表单的接口也要做足校验行为,通过前后端共同控制输...

乌柏木33阅读 6.1k评论 9

2 声望
1 粉丝
宣传栏