PDF.js 2种使用方式,跨域使用

前言

因为工作需要,开发移动端在线阅读PDF文档。所以找到了PDF.js,但PDF文件是储存在另外独立服务器,所以常规使用PDF.js会存在问题,经过搜索查询,实践解决了问题。

这边提供尝试过的2种有效方法

1.绘制页面

html 

< div >
< h1 >< a href= "javascript:void(0)" target= "_blank" onclick= "showPdf()" >显示pdf文档 </ a ></ h1 >
< div id= "container" style= "display: none;" >
< div class= "lightbox" ></ div >
< div id= "pop" class= "pop" ></ div >
</ div >
</ div >


js

< script src= "https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js" > < / script >
< script src= "./pdfjs/build/pdf.js" type= "text/javascript" > < / script >
< script src= "./pdfjs/build/pdf.worker.js" type= "text/javascript" > < / script >
< script type= "text/javascript" >
function showall(url, page, id) {
PDFJS.getDocument(url).then( function getPdfHelloWorld(pdf) {
pdf.getPage(page).then( function getPageHelloWorld(page) {
var scale = 1.0;
var viewport = page.getViewport(scale);
var canvas = document.getElementById(id);
var context = canvas.getContext( '2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
});
});
}

function showPdf() {
var url = 'http://otdddh8nn.bkt.clouddn.com/yxxj.pdf'; //pdf文件地址
$( "#container").show();
$( "#pop").empty();
PDFJS.getDocument(url).then( function getPdfHelloWorld(pdf) {
pages = pdf.numPages;
for( var i = 1; i < pdf.numPages; i++) {
var id = 'page-id-' + i;
$( "#pop").append( '<canvas id="' + id + '"></canvas>');
showall(url, i, id);
}
});
}

< / script >

引入 pdf.worker.js 、 pdf.js  两个文件和jq,通过调用文件api绘制PDF页面.

特点 可以根据自己需要构建页面,对手机网速有要求。

备注 苹果6 ios11系统会报Unhandled Promise Rejection: UnexpectedResponseException: Unexpected server response (206) while retrieving PDF  可能和存储服务器不支持断点续传有关系(有知道的大佬可以告诉我下)所以后面改用以下方法。

2.使用viewer.html

html

< iframe style= "width:100%;height:100%;" src= "./pdfjs/web/viewer.html?pdf_url=http://otdh8nn.bkt.clouddn.com/yxxj.pdf" >

</ iframe >


viewer.js 注释掉 DEFAULT_URL

新建viewer.php 

<?php
echo file_get_contents($_GET[ 'pdf_url']);

viewer.html 页面底部添加

< script >

    var DEFAULT_URL = './viewer.php?pdf_url='+getQueryStringByName( 'pdf_url');

    function getQueryStringByName(name){
var result = location.search.match( new RegExp( "[\?\&]" + name+ "=([^\&]+)", "i"));
if(result == null || result.length < 1){
return "";
}
return result[ 1];
    }
< / script >

在页面添加 iframe 标签打开viewer.html  传参数pdf_url 值为pdf地址 ;

在viewer.html 修改默认地址default_url 为viewer.php,传参数pdf_url ;

而在viewer.php页面将pdf_url 网址的pdf文件读取成字符串返回给前台显示 。

特点 速度很快,上方有菜单,可以根据自己需要修改注释掉了菜单部分功能。

单独传参可以打开页面,实现跨域访问

http://localhost/web/pdfjs/web/viewer.html?pdf_url =http://otq6dd8nn.bkt.clouddn.com/yxxj.pdf


补充 

个人使用的是 pdfjs-1.9 版本 包含web和build2个文件夹

pdfjs-1.9下载


官方FAQ
Can I load a PDF fromanother server (cross domain request)?能否从其它服务器读取pdf文件(跨域访问)?

Notby default, but it is possible. PDF.js runs with the same permissions as anyother JavaScript code, which means it cannot do cross origin requests (see Same origin policy and an example).There are some possible ways to get around this such as using CORS (seealso unsafeheaders issue and Access-Control-Expose-Headersissue) or setting up a proxy on your server thatwill feed PDF.js the PDF file. Both workarounds are out of the scope of thePDF.js project and we will not provide code to do either.

不默认,但它是可能的。 PDF.js运行具有相同权限的任何其他JavaScript代码,这意味着它不能跨出自身请求(见同根同源的政策和示例) 。有一些可能的方法来解决这个问题,如使用CORS (seealso unsafe headers issue and Access-Control-Expose-Headersissue),或者设置你的服务器上的代理,将PDF文件提供给PDF.js。这两种解决方法都出了PDF.js项目的范围,我们将不提供代码,请执行。


第二种方法实际上就是用php自身先读取文档再打开,网上有说用读取文件流方式可行,原理一致

我个人php 没有仔细研究   但java一般都是采用这个方法。

也贴一下代码

function getStream(){
    $filepath = 'http://otq68ddnn.bkt.clouddn.com/yxxj.pdf';
    $fp = fopen($filepath, "r");
    Header( 'Content-Type: application/pdf');
    header( 'Access-Control-Allow-Origin:*');
     //Header("Content-type: application/octet-stream");
    Header( "Accept-Ranges: bytes");
    Header( "Content-Disposition: attachment; filename=yxxj.pdf");
    $buffer = 1024;
     while (!feof($fp)) {
    $file_con = fread($fp,$buffer);
     echo $file_con;
    }

    fclose($fp);
    
}

function sendfile( $fullPath ){
    $fsize = filesize($fullPath);
    header( "Pragma: public");
    header( "Expires: 0");
    header( "Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header( "Cache-Control: private", false);
    header( "Content-Type: application/pdf");
    header( 'Access-Control-Allow-Origin:*');
    Header( "Accept-Ranges: bytes");
    header( "Content-Disposition: attachment; filename=\"".basename($fullPath). "\";" );
    header( "Content-Transfer-Encoding: binary");
    header( "Content-Length: ".$fsize);
    ob_clean();
    flush();
    readfile( $fullPath );
}


感谢 参考来源

pdf.js专题

第一方法参考

第二方法参考



2018-05-21 更新

JAVA实现

后面又用java开发了web版本,也贴下代码。

1.java服务端 这里我是直接写在servlet,其他需要自己创建 response 

直接从云服务器获取数据,输出给前端

response.setContentType("application/pdf");
ServletOutputStream sos = response.getOutputStream();
					
String destUrl="http://osq69h8nn.bkt.clouddn.com/BB8B.pdf";
URL url = new URL(destUrl);
HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();
//连接指定的网络资源
httpUrl.connect();
//获取网络输入流
BufferedInputStream bis = new BufferedInputStream(httpUrl.getInputStream());
int b;
while((b = bis.read())!=-1) {
	sos.write(b);
}
sos.close();
bis.close();
return;

如果是读取服务器文件,可以改为读取文件方式(我的做法是读取WEB-INF下的PDF文件,微笑)

InputStream is = new FileInputStream(path);


2.viewer.html 添加,务必放在 引用viewer.js前面 或者直接写到viewer.js前面

<script>
	//获取数据流
	var PDFData = ""; //定义一个空变量  
	$.ajax({  
	    type: "get", //如果报405错误就把post改成get  
	    async: false,  
	    mimeType: 'text/plain; charset=x-user-defined',  
	    url: "../../article.do?type=getPdf", //请求服务器数据 
	    success: function(data) {  
		        PDFData = data; //data就是byte[]数组,下面有介绍  
	    }  
	});  
	var rawLength = PDFData.length;  
	//转换成pdf.js能直接解析的Uint8Array类型,见pdf.js-4068    
	var array = new Uint8Array(new ArrayBuffer(rawLength));  
	for (var i = 0;i < rawLength; i++) {  
		 array[i] = PDFData.charCodeAt(i) & 0xff;  
	}  
	var pdf_url = array;  
	//-----------
	 
</script>

3.viewer.js 修改

var DEFAULT_URL = pdf_url;

唯一要注意的就是 js请求方法的调用


  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anciend

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值