作者:荣星树 | 来源:互联网 | 2023-06-25 07:50
pdf.js远程跨域访问+访问文件流
前言:使用pdf.js之前首先得确定需要访问是的本项目PDF文件,还是远程PDF文件还是PDF文件,还是本地文件流,还是远程PDF文件流。我这里使用的是远程文件流的路径(具我目前的理解:文件流路径是可以直接访问下载的)。网上有很多教程,要么只是讲pdf.js跨域访问,要么就是pdf.js的文件流访问。所以会有有些人访问不到的情况。就因为我的是PDF文件流路径。这里就记录一下我遇到跨域访问文件流的过程。
- 下载pdf.js 官网。这里就不多介绍,网上很多有关结构目录的介绍。可以查看有关资料。
- 将下载的文件夹整个拷贝到项目中(我这里使用的是目前最新的pdfjs-2.5.207-dist)。这属于前端页面,只要拷贝到能访问页面的地方就可以了。如下图:
- 这里需要处理两个问题:跨域和访问文件流。
对于本项目中的PDF文件来说,访问很简单:如下代码:
<a href&#61;&#39;../js/pdfjs-2.5.207-dist/web/viewer.html?file&#61;PDF文件&#39;>点击预览a>
对于远程PDF文件的处理&#xff1a;首先需要修改两个文件的内容&#xff0c;viewer.html和viewer.js。
- 先说viewer.js文件&#xff0c;文件代码较多&#xff0c;建议使用搜索的方式&#xff1a;
找到以下代码&#xff1a;
function webViewerLoad() {var config &#61; getViewerConfiguration();window.PDFViewerApplication &#61; pdfjsWebApp.PDFViewerApplication;window.PDFViewerApplicationOptions &#61; pdfjsWebAppOptions.AppOptions;var event &#61; document.createEvent(&#39;CustomEvent&#39;);event.initCustomEvent(&#39;webviewerloaded&#39;, true, true, {});document.dispatchEvent(event);pdfjsWebApp.PDFViewerApplication.run(config);
}
修改代码如下&#xff0c;可以将上面的代码注释掉&#xff0c;加入下面代码&#xff0c;我就是这样做的&#xff1a;
window.webViewerLoad&#61;function webViewerLoad(fileUrl) {var config &#61; getViewerConfiguration();window.PDFViewerApplication &#61; pdfjsWebApp.PDFViewerApplication;window.PDFViewerApplicationOptions &#61; pdfjsWebAppOptions.AppOptions;var event &#61; document.createEvent(&#39;CustomEvent&#39;);event.initCustomEvent(&#39;webviewerloaded&#39;, true, true, {});document.dispatchEvent(event);if(fileUrl){config.defaultUrl&#61;fileUrl;}pdfjsWebApp.PDFViewerApplication.run(config);
}
- 注释掉以下代码&#xff0c;这段代码就在上面代码之下呢&#xff1a;
if (document.readyState &#61;&#61;&#61; &#39;interactive&#39; || document.readyState &#61;&#61;&#61; &#39;complete&#39;) {webViewerLoad();
} else {document.addEventListener(&#39;DOMContentLoaded&#39;, webViewerLoad, true);
}
run: function run(config) {this.initialize(config).then(webViewerInitialized);}
run(config) {this.initialize(config).then(webViewerInitialized);
},
修改代码如下&#xff1a;
run: function run(config) {if(config.defaultUrl){_app_options.AppOptions.set(&#39;defaultUrl&#39;,config.defaultUrl)} this.initialize(config).then(webViewerInitialized);
},
run(config) {if(config.defaultUrl){_app_options.AppOptions.set(&#39;defaultUrl&#39;,config.defaultUrl)}this.initialize(config).then(webViewerInitialized);},
- 接下来是viewer.html文件了&#xff0c;修改之前一定要引入jquery文件&#xff0c;因为这里需要用到ajax请求&#xff0c;解决跨域问题。以下加入的代码不需要更改&#xff0c;便可直接使用。
<script type&#61;"text/Javascript">$(()&#61;>{var url &#61; getUrlParam("urlPath");console.log(url)xhrPdf(url,function(href){webViewerLoad(href)})})function getUrlParam(name) {var reg &#61; new RegExp("(^|&)" &#43; name &#43; "&#61;([^&]*)(&|$)"); var r &#61; window.location.search.substr(1).match(reg); if (r !&#61; null) return unescape(r[2]); return null; }function xhrPdf(urlPath,callback) {$.ajax({type: "post",async: false,mimeType: &#39;text/plain; charset&#61;x-user-defined&#39;,url: "/WechatApp/manual/pdfStreamHandler", data:{urlPath:urlPath},success: function(data) {var rawLength &#61; data.length;var array &#61; new Uint8Array(new ArrayBuffer(rawLength));for (var i &#61; 0;i < rawLength; i&#43;&#43;) {array[i] &#61; data.charCodeAt(i) & 0xff;}var href &#61; window.URL.createObjectURL(new Blob([array]));callback(href) }});}script>
- 这里并没有真正解决跨域问题&#xff0c;通过间接转换的方式解决的。主要是通过调用后端mapping&#xff0c;将PDF文件转为PDF文件流来操作的&#xff0c;这个网上教程到处都是。但是如果已经知道的路径就是PDF文件流了怎么办&#xff1f;这里就需要在后端controller中创建一个请求&#xff0c;作相应的处理&#xff0c;然后把流数据传到前端&#xff0c;这样前端就可以访问了PDF文件了。
我这里处理如下&#xff1a;创建如下mapping
&#64;RequestMapping(value &#61; "/pdfStreamHandler")public void getRemoteFile(String urlPath, HttpServletResponse response) {InputStream inputStream &#61; null;try {try {String strUrl &#61; urlPath.trim();URL url &#61; new URL(strUrl);URLConnection connection &#61; url.openConnection();HttpURLConnection httpURLConnection &#61; (HttpURLConnection) connection;httpURLConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");inputStream &#61; httpURLConnection.getInputStream();int bytesum &#61; 0;int byteread &#61; 0;byte[] buffer &#61; new byte[1024];response.reset();response.addHeader("Content-Disposition", "attachment;filename&#61;" &#43; new String("cbzm.pdf".getBytes()));OutputStream toClient &#61; new BufferedOutputStream(response.getOutputStream());response.setContentType("application/octet-stream");bytesum &#61; 0;byteread &#61; 0;buffer &#61; new byte[1024];while ((byteread &#61; inputStream.read(buffer)) !&#61; -1) {bytesum &#43;&#61; byteread;toClient.write(buffer, 0, byteread);}toClient.flush();inputStream.close();toClient.close();} catch (IOException e) {e.printStackTrace();inputStream &#61; null;}} catch (Exception e) {e.printStackTrace();inputStream &#61; null;}}
<a href&#61;&#39;../js/pdfjs-2.5.207-dist/web/viewer.html?urlPath&#61;PDF路径即可&#39;>点击预览a>
- 参考文章&#xff1a;
- https://blog.csdn.net/wf001015/article/details/93307643?utm_medium&#61;distribute.pc_relevant.none-task-blog-baidulandingword-2&spm&#61;1001.2101.3001.4242
- https://blog.csdn.net/baby97/article/details/83410628
- https://www.cnblogs.com/best-coder/p/11550409.html