pdf.js 如何实现跨域问题?在网上搜索了很多资料,有n种解决方案。这里我采用了xhr2+createObejectUrl的方式实现。
准备工作:
1.下载最新的pdf.js,我使用的是pdfjs-2.1.266-dist这个版本
2.对viewer.js进行调整:
2.1在viewer.js找到这段代码:
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);
}
改成:
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 语句
if(fileUrl){
config.defaultUrl=fileUrl;
}
pdfjsWebApp.PDFViewerApplication.run(config);
}
2.2把下面这段代码注释掉
if (document.readyState === 'interactive' || document.readyState === 'complete') {
webViewerLoad();
} else {
document.addEventListener('DOMContentLoaded', webViewerLoad, true);
}
2.3找到这段代码
run: function run(config) {
this.initialize(config).then(webViewerInitialized);
},
改成:
run: function run(config) {
//添加if语句
if(config.defaultUrl){
_app_options.AppOptions.set('defaultUrl',config.defaultUrl)
}
this.initialize(config).then(webViewerInitialized);
},
参考:
https://blog.csdn.net/wangzhikui1/article/details/87817192#commentsedit
3.viewer.html引用jquery添加代码:
$(document).ready(function () {
//获取要跨域访问的pdf地址
var pdfUrl=Request.QueryString["pdfurl"];
xhrPdf(pdfUrl,function(href){
//调用viewer.js方法预览pdf
webViewerLoad(href)
})
});
//添加xhrPdf函数
function xhrPdf(url,callback) {
$.ajax({
type: "get",
async: false,
mimeType: 'text/plain; charset=x-user-defined',
url: httpurl + "spring/WXApi/getpdf?pdfurl="+url, //请求服务器数据 获取pdf数据流
success: function(data) {
var rawLength = data.length;
//转换成pdf.js能直接解析的Uint8Array类型,见pdf.js-4068
var array = new Uint8Array(new ArrayBuffer(rawLength));
for (var i = 0;i < rawLength; i++) {
array[i] = data.charCodeAt(i) & 0xff;
} 、
var href = window.URL.createObjectURL(new Blob([array]));//数据流转换成createObjectURL能解析的Blob类型
callback(href) //返回url
}
});
}
4.服务端通过HttpURLConnection跨域获取pdf数据流,并返回数据流到客服端
java代码:
@RequestMapping(value = "/getpdf", method = { RequestMethod.GET,RequestMethod.POST })
public void getpdf(String pdfurl,HttpServletRequest req, HttpServletResponse resp) throws IOException
{
if(pdfurl==null)
{
pdfurl="";
}
resp.setContentType("application/pdf");
OutputStream sos = resp.getOutputStream();
String destUrl=pdfurl;
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;
}
这样可就跨域访问pdf文件了。这样做的好处是不占存储空间,不需要把pdf文件下载下来保存到本地。
原理:通过后端跨域把pdf转换成数据流,客户端通过xhr2+createObejectUrl把数据流转成可本地访问的url,在把url传给viewer.js实现跨域访问。
此方法通过微信内置浏览器和支付宝内置浏览器访问。