使用pdfjs自带的viewer预览pdf文件可以支持跨域

本文介绍如何使用xhr2和createObjectUrl解决PDFJS预览跨域文件的问题,通过自定义xhrPdf函数和修改viewer.js,实现跨域PDF文件的本地化加载,从而在网页中顺利预览。

pdfjs默认不支持预览跨域文件,但可以使用xhr2+createObejectUrl解决,具体改动如下:

//添加xhrPdf函数,这个函数写在哪里都可以
function xhrPdf(url,callback) {
 
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);//get请求,请求地址,是否异步
    xhr.responseType = "blob";    // 返回类型blob
    xhr.onload = function () {// 请求完成处理函数
        if (this.status === 200) {

            var blob = this.response;// 获取返回值
            var href = window.URL.createObjectURL(blob);
            callback(href)
            // location.href=href
            // location.href='viewer.html?file='+url

            // blobToDataURL(blob,function(data){
            //     console.log(data)

            // })

        }
    
    // 发送ajax请求
    xhr.send();

}

修改viewer.js里面的内容:
第一处修改为:

window.webViewerLoad=function webViewerLoad(fileUrl) {//调整了此行
  var config = getViewerConfiguration();
  window.PDFViewerApplication = pdfjsWebApp.PDFViewerApplication;
  window.PDFViewerApplicationOptions = pdfjsWebAppO
<think> 我们参考了用户提供的多个引用,特别是引用[3]和引用[4]与Vue2中预览PDF并实现文字搜索高亮的需求密切相关。以下将分步骤说明在Vue2中如何实现。 核心思路: 1. 使用pdf.js自带viewer.html作为预览入口,并传递PDF文件地址(可以是URL或经过处理的blob URL)。 2. 通过修改viewer.html的参数或利用pdf.js提供的API来实现文字搜索高亮。 步骤: ### 1. 引入pdf.js 首先,需要将pdf.js的库文件放入项目的静态资源目录(例如`public/static/pdf`)。可以从[pdf.js官网](https://mozilla.github.io/pdf.js/)下载预构建的版本(例如选择`pdfjs-3.4.120-dist.zip`)。解压后,将整个文件夹(通常包含`build`和`web`两个子文件夹)放入`public/static/pdf`目录中。 ### 2. 在Vue组件中使用iframe嵌入viewer.html 在Vue2项目中,我们可以使用iframe来嵌入pdf.js提供的viewer.html,并传递PDF文件的路径。 ```vue <template> <div> <!-- 搜索框 --> <div> <input type="text" v-model="searchText" placeholder="输入搜索内容"> <button @click="search">搜索</button> </div> <!-- PDF预览框 --> <iframe ref="pdfViewer" :src="pdfViewerUrl" width="100%" height="600px" frameborder="0"></iframe> </div> </template> <script> export default { data() { return { // 假设PDF文件路径,可以是相对路径(放在public目录下)或者网络URL // 如果是文件流,需要先转换为Blob URL(后面会说明) pdfPath: 'example.pdf', // 或者使用blob URL searchText: '', // 计算pdf查看器的URL,注意指向public目录下的viewer.html pdfViewerUrl: '' }; }, mounted() { // 初始化pdfViewerUrl,注意文件路径需要编码 this.updateViewerUrl(); }, methods: { updateViewerUrl() { // 注意:如果pdfPath是本地public目录下的文件,直接使用相对路径 // 如果是blob URL,需要确保viewer.html能够访问,但注意blob URL可能存在同源限制 let fileParam = encodeURIComponent(this.pdfPath); this.pdfViewerUrl = `/static/pdf/web/viewer.html?file=${fileParam}`; }, search() { // 获取iframe的window对象 const iframe = this.$refs.pdfViewer; if (iframe && this.searchText) { // 向pdf viewer发送消息,触发搜索 iframe.contentWindow.postMessage({ type: 'search', text: this.searchText }, '*'); // 注意:生产环境应避免使用'*',指定确切的origin } } } }; </script> ``` ### 3. 实现搜索高亮 pdf.js的viewer.html默认支持搜索功能(通过快捷键Ctrl+F或菜单),但我们希望从外部控制搜索。这需要通过postMessage与viewer.html中的PDFViewerApplication进行通信。 但是,标准的viewer.html并没有提供外部直接触发搜索的API。因此,我们需要修改viewer.html或添加自定义脚本。 根据引用[3]中的方法,我们可以修改pdf.js的源码来实现: 步骤: - 在`viewer.html`中,我们可以添加一个自定义的事件监听器,用来接收外部消息并触发搜索。 - 修改`viewer.js`(或`viewer.mjs`)源码,添加对`window.addEventListener('message', ...)`的处理。 具体修改如下(以pdf.js v3.4.120为例): 在`web/viewer.js`中找到类似下面的代码位置(通常在初始化代码附近): ```javascript // 在viewer.js的顶部或初始化部分之后,添加消息监听 window.addEventListener("message", function(event) { var data = event.data; if (data && data.type === 'search') { // 调用pdf.js内部的搜索功能 PDFViewerApplication.findBar.open(); PDFViewerApplication.findBar.findField.value = data.text; PDFViewerApplication.findBar.highlightAll.checked = true; PDFViewerApplication.findBar.dispatchEvent(""); // 触发输入事件 PDFViewerApplication.findBar.findNextButton.click(); } }); ``` 注意:由于pdf.js版本不同,内部变量名可能略有差异。上述代码仅供参考,可能需要调整。 ### 4. 处理文件流 如果PDF文件是通过接口返回的文件流(如后端API返回的二进制流),我们需要将其转换为Blob URL,然后再传递给viewer.html。 在Vue组件中,我们可以使用axios获取文件流: ```javascript axios.get('/api/get-pdf', { responseType: 'blob' }).then(response => { const blob = new Blob([response.data], {type: 'application/pdf'}); const blobUrl = URL.createObjectURL(blob); this.pdfPath = blobUrl; this.updateViewerUrl(); // 更新iframe的src }); ``` ### 注意事项 - 修改pdf.js源码可能会在升级版本时带来维护问题,因此建议记录修改点。 - 不同版本的pdf.js可能存在差异,请根据实际版本调整。 - 生产环境部署时,注意pdf.js的资源路径是否正确。 以上就是在Vue2中使用pdf.js预览PDF并实现文字搜索高亮的主要步骤。 由于修改pdf.js源码需要谨慎,也可以考虑另一种方式:将PDF渲染到Canvas上,然后利用pdf.js的文本层进行搜索高亮。这种方式更灵活但实现起来更复杂,此处不展开。 如果需要更详细的代码示例,可以参考引用[3]中的具体实现。 §§相关问题§§ 1. 如何修改pdf.js的源码以实现自定义搜索功能? 2. 在Vue2中如何处理PDF文件预览? 3. 如何解决pdf.js在移动端的适配问题? </think> 以下是在 Vue2 中使用 pdf.js 预览 PDF 文件并实现文字搜索高亮的完整方案,结合引用内容和技术实践: ### 一、基础配置步骤 1. **引入 pdf.js 库** ```bash # 下载 pdf.js(推荐 v2.10+) wget https://github.com/mozilla/pdf.js/releases/download/v2.10.377/pdfjs-2.10.377-dist.zip ``` 解压后将 `build` 和 `web` 文件夹放入项目 `public/static/pdf` 目录 2. **Vue 组件嵌入预览器** ```vue <template> <div> <!-- 搜索框 --> <input v-model="searchText" @keyup.enter="searchInPDF"> <button @click="searchInPDF">搜索</button> <!-- 预览容器 --> <iframe ref="pdfViewer" :src="viewerUrl" width="100%" height="800px" frameborder="0"> </iframe> </div> </template> <script> export default { data() { return { searchText: '', pdfUrl: 'https://example.com/document.pdf', // PDF 文件 URL viewerUrl: '' } }, mounted() { // 初始化查看器 URL const encodedUrl = encodeURIComponent(this.pdfUrl); this.viewerUrl = `/static/pdf/web/viewer.html?file=${encodedUrl}`; }, methods: { searchInPDF() { const iframe = this.$refs.pdfViewer; if (iframe && this.searchText) { // 向 PDF 查看器发送搜索指令 iframe.contentWindow.postMessage({ type: 'search', text: this.searchText }, '*'); } } } } </script> ``` ### 二、搜索高亮实现关键 1. **修改 `viewer.js` 源码**(位于 `web/viewer.js`) 添加消息监听代码: ```javascript window.addEventListener("message", event => { const { type, text } = event.data; if (type === "search") { // 触发 PDF 内部搜索功能 PDFViewerApplication.findBar.open(); PDFViewerApplication.findBar.findField.value = text; PDFViewerApplication.findBar.highlightAll.checked = true; PDFViewerApplication.findBar.dispatchEvent(""); // 触发搜索 } }); ``` 2. **支持文件预览**(若后端返回二进制流) ```javascript axios.get('/api/pdf', { responseType: 'blob' }).then(res => { const blob = new Blob([res.data], { type: 'application/pdf' }); this.pdfUrl = URL.createObjectURL(blob); this.viewerUrl = `/static/pdf/web/viewer.html?file=${encodeURIComponent(this.pdfUrl)}`; }); ``` ### 三、注意事项 1. **路径配置** - Vue2 静态资源需放在 `public/static` 目录 - 使用绝对路径:`/static/pdf/web/viewer.html` 2. **搜索优化** - 高亮所有匹配项:在 `viewer.js` 中设置 `highlightAll.checked = true` - 支持特殊字符:修改 `web/viewer.js` 中的 `convertToRegExpString()` 方法,移除不必要的转义字符[^3] 3. **移动端适配** ```css /* 在组件中添加 */ iframe { height: calc(100vh - 120px); } ``` ### 四、备选方案(Canvas 渲染) 若需更高定制性,可采用 Canvas 渲染方案: ```javascript // 安装依赖 npm install pdfjs-dist // 在组件中 import * as pdfjsLib from 'pdfjs-dist/webpack'; async renderPDF() { const loadingTask = pdfjsLib.getDocument(this.pdfUrl); const pdf = await loadingTask.promise; // 逐页渲染到 Canvas for (let i = 1; i <= pdf.numPages; i++) { const page = await pdf.getPage(i); // 渲染逻辑(可添加文本层实现精准搜索高亮) } } ``` > **重要提示**:使用 iframe 方案时需确保查看器页面与应用同源,场景需配置 `web/viewer.html` 的 CORS 响应头[^4]。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值