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( ''">');
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 

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前面

3.viewer.js 修改

var DEFAULT_URL = pdf_url;

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


你可能感兴趣的:(新手)