通过文件流的方式解决PDF.js的跨域问题
最近在使用PDF.js的过程中,需要让PDF.js预览url的pdf文件,本地文件是通过直接传入文件名的形式可以直接获取的,但是url的话会发生跨域问题,笔者这边尝试了许多方法,随后使用文件流的方式解决了,做一些分享。
·
最近在使用PDF.js的过程中,需要让PDF.js预览url的pdf文件,本地文件是通过直接传入文件名的形式可以直接获取的,但是url的话会发生跨域问题,笔者这边尝试了许多方法,随后使用文件流的方式解决了,做一些分享。
问题阐述
首先看普通的显示方式,是通过本地文件
的形式进行显示的。
// 文件名
let fileName = 'test.pdf'
// 调用PDF.js的控件
let pdfLink = '/plugins/pdfjs/web/viewer.html?file=' + fileName
// 更新iFrame的src路径进行显示
$('#printIframe').prop('src', pdfLink)
这样是没什么问题的
那么问题来了,如果传入的是url
的形式呢?
// url
let fileName = 'http://XXXXXXX/XXX.pdf'
// 调用PDF.js的控件
let pdfLink = '/plugins/pdfjs/web/viewer.html?file=' + fileName
// 更新iFrame的src路径进行显示
$('#printIframe').prop('src', pdfLink)
这样的话会直接报错跨域问题
但是我们请求的是外部网络,无法更改服务器配置,所以这边最后使用了文件流的方式进行解决。
解决办法
首先把文件的url的请求ajax,在后台进行下载,然后把下载好的文件流传送到前台,再将文件流转换成blob形式,再将blob对象创建一个新的url,可以解析的url,随后再把新url传送给PDF.js
前端Ajax部分
// url
let fileName = 'http://XXXXXXX/XXX.pdf'
$.ajax({
url : '/download?filename=' + encodeURIComponent(fileName),
type: 'post',
dataType: 'blob',
mimeType: 'text/plain; charset=x-user-defined',
complete: (response) => {
// 将文件流转换成blob形式
let rawLength = response['responseText'].length;
let array = new Uint8Array(new ArrayBuffer(rawLength));
for (let i = 0; i < rawLength; i++) {
array[i] = response['responseText'].charCodeAt(i) & 0xff;
}
const blob = new Blob([array], {type: 'application/pdf;charset=utf-8'});
let url = window.URL || window.webkitURL;
// 将blob对象创建新的url
const blobUrl = url.createObjectURL(blob);
// 将url传送到PDF.js
let pdfLink = '/plugins/pdfjs/web/viewer.html?file=' + blobUrl;
// iframe画面更新
$('#printIframe').prop('src', pdfLink);
}
});
后端Java部分
// 接口部分
@RequestMapping("/download")
@ResponseBody
public void fileDownload(@RequestParam("filename") String filename,
HttpServletResponse response) throws UnsupportedEncodingException {
// 通过网络获取文件流
DownloadUtils.getFileStream(filename, response);
}
// 下载工具部分
// 将文件流传送到response
public static void getFileStream(String filename, HttpServletResponse response) {
try {
// 根据文件url下载文件
openFile(filename, response);
} catch (Exception e) {
logger.error("下载失败!");
}
}
// 通过url下载文件的方法
private static void openFile(String filePath, HttpServletResponse response) {
// 服务器状态
int HttpResult;
try {
// URL
URL url = new URL(filePath);
// URL连接对象
URLConnection urlconn = url.openConnection();
urlconn.connect();
HttpURLConnection httpconn = (HttpURLConnection) urlconn;
HttpResult = httpconn.getResponseCode();
if (HttpResult != HttpURLConnection.HTTP_OK) {
logger.error("网络连接失败");
throw new ConnectException("网络连接失败");
} else {
InputStream in = urlconn.getInputStream();
try {
String fileName = "test.pdf";
response.setContentType("application/pdf;charset=utf-8");
response.addHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
int b = 0;
byte[] buffer = new byte[512];
while (b != -1) {
b = in.read(buffer);
if (b != -1) {
response.getOutputStream().write(buffer, 0, b);
}
}
} catch (Exception e) {
e.printStackTrace();
logger.error("文件取得失败");
} finally {
try {
if (in != null) {
in.close();
}
response.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
logger.error("文件取得失败");
}
}
}
} catch (Exception e) {
e.printStackTrace();
logger.error("文件取得失败");
}
}
显示结果
随后发现通过url也是可以正常显示了,笔者这边亲测是没有问题,如果有问题欢迎与我留言。
更多推荐
已为社区贡献2条内容
所有评论(0)