解决pdf.js不支持跨域问题
解决跨域问题
首先直接打开任何一个链接pdf文件是不存在跨域问题的,正是因为pdf.js需要通过ajax以文件流的形式去解析才造成了跨域问题。
当pdf.js从 http://localhost 请求 http://localhost:8081/files/demo.pdf , 很遗憾啊,pdf.js发出了个警告:
file origin does not match viewer's
因为当前源与目标源不一样,pdf.js直接拦截了。
解决方法一(代理方式):
在http://localhost 服务器配置代理,nginx如下:
location /files {
proxy_pass http://localhost:8081/;
}
使用方法,不要带上前缀
http://localhost/pdf.js/web/viewer.html?file=/demo.pdf
这种方法有缺点:
1、不能使用完整链接,如:http://localhost:8081/files/demo.pdf
2、如果目标存在多个目录需要增加配置,如: /files/demo.pdf 、 /pdf/demo.pdf
解决方法二(配置CORS跨域):
在目标服务器 http://localhost:8081 新增下面头部即可。
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS
Access-Control-Expose-Headers: Accept-Ranges, Content-Encoding, Content-Length, Content-Range
nginx(其他服务器类似):
location / {
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET, POST, PUT, OPTIONS';
add_header Access-Control-Expose-Headers 'Accept-Ranges, Content-Encoding, Content-Length, Content-Range';
}
使用方法:
http://localhost/pdf.js/web/viewer.html?file=http://localhost:8081/demo.pdf
以为这样就大功告成了吗? 很遗憾,还是报了之前的错误
file origin does not match viewer's
翻了翻官方文档,然而没有找到解决方案。但是并不能主档我前进,现在只好从源码入手。
在viewer.js文件里搜索关键字 (file origin does not match),哈哈真的有 (本来就有的好吗)。
贴下关键代码, 在1863行左右:
{
var HOSTED_VIEWER_ORIGINS = ['null', 'http://mozilla.github.io', 'https://mozilla.github.io'];
validateFileURL = function validateFileURL(file) {
if (file === undefined) {
return;
}
try {
var viewerOrigin = new URL(window.location.href).origin || 'null';
if (HOSTED_VIEWER_ORIGINS.indexOf(viewerOrigin) >= 0) {
return;
}
var fileOrigin = new URL(file, window.location.href).origin;
if (fileOrigin !== viewerOrigin) {
throw new Error('file origin does not match viewer\'s');
}
} catch (ex) {
var message = ex && ex.message;
PDFViewerApplication.l10n.get('loading_error', null, 'An error occurred while loading the PDF.').then(function (loadingErrorMessage) {
PDFViewerApplication.error(loadingErrorMessage, { message: message });
});
throw ex;
}
};
}
这里使用了try捕捉错误,注意第2个条件语句,因为当前源与目标源不一样,所以抛出了异常。
if (fileOrigin !== viewerOrigin) {
// throw new Error('file origin does not match viewer\'s');
}
很好解决,只要把throw这行注释即可。 这就到此结束了,完美解决跨域问题。