pdf.jsリモートクロスドメインアクセス+アクセスファイルフロー
はじめに:pdf.jsを使用する前に、まず、このプロジェクトのPDFファイル、リモートPDFファイル、PDFファイル、ローカルファイルストリーム、またはリモートPDFファイルストリームにアクセスする必要があるかどうかを判断する必要があります。ここで使用するのは、リモートファイルストリームのパスです(私の現在の理解では、ファイルストリームパスに直接アクセスしてダウンロードできます)。インターネット上には、pdf.jsのクロスドメインアクセス、またはpdf.jsのファイルストリームアクセスに関するチュートリアルが多数あります。そのため、一部の方がアクセスできない場合があります。私がPDFファイルのストリームパスだからです。これは、ファイルストリームへのクロスドメインアクセスに遭遇した方法の記録です。
- pdf.js公式ウェブサイトをダウンロードしてください。ここではあまり紹介はありませんが、インターネット上のカタログの構造については多くの紹介があります。関連情報を表示できます。
- ダウンロードしたフォルダ全体をプロジェクトにコピーします(ここでは最新のpdfjs-2.5.207-distを使用しています)。これはフロントエンドページです。ページにアクセスできる場所にコピーするだけです。以下に示すように:
- ここでは、クロスドメインとファイルストリームへのアクセスという2つの問題に対処する必要があります。
このプロジェクトのPDFファイルの場合、アクセスは非常に簡単です。次のコード:
<!-- ../js/pdfjs-2.5.207-dist/web/viewer.html是viewer.html的访问路径,file=后面是PDF文件路径。还有其他的访问方式,这里就不多介绍了,网上有很多 -->
<a href='../js/pdfjs-2.5.207-dist/web/viewer.html?file=PDF文件'>点击预览</a>
リモートPDFファイル処理の場合:最初に、viewer.htmlとviewer.jsの2つのファイルのコンテンツを変更する必要があります。
- 最初に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);
}
- 次のコードをコメントアウトします。このコードは上記のコードの下にあります。
if (document.readyState === 'interactive' || document.readyState === 'complete') {
webViewerLoad();
} else {
document.addEventListener('DOMContentLoaded', webViewerLoad, true);
}
- 次のコードを見つけます。
run: function run(config) {
this.initialize(config).then(webViewerInitialized);
}
//我的文件中不是这样的,是下面代码,两者是一样的
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);
},
//我的修改是如下,其实一样
run(config) {
//添加if语句
if(config.defaultUrl){
_app_options.AppOptions.set('defaultUrl',config.defaultUrl)
}
this.initialize(config).then(webViewerInitialized);
},
- 次はviewer.htmlファイルです。クロスドメインの問題を解決するにはajaxリクエストが必要なため、変更する前にjqueryファイルを導入する必要があります。以下に追加されたコードは変更する必要がなく、直接使用できます。
<!-- 在<script src="viewer.js"></script>之前引入以下代码,再次强调,需要引入jquery -->
<script type="text/javascript">
$(()=>{
//获取要跨域访问的pdf地址
var url = getUrlParam("urlPath");
console.log(url)
xhrPdf(url,function(href){
//调用viewer.js方法预览pdf
webViewerLoad(href)
})
})
//获取url中的参数
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if (r != null) return unescape(r[2]); return null; //返回参数值
}
//添加xhrPdf函数
function xhrPdf(urlPath,callback) {
$.ajax({
type: "post",
async: false,
mimeType: 'text/plain; charset=x-user-defined',
url: "/WechatApp/manual/pdfStreamHandler", //请求服务器数据 获取pdf数据流,
data:{
urlPath:urlPath
},
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
}
});
}
</script>
- ここではクロスドメインの問題に対する実際の解決策はありません。間接的な変換によって解決されます。これは主に、バックエンドマッピングを呼び出してPDFファイルをPDFファイルストリームに変換することによって操作されます。このオンラインチュートリアルはどこにでもあります。しかし、既知のパスがPDFファイルストリームである場合はどうなりますか?ここでは、バックエンドコントローラでリクエストを作成し、対応する処理を実行してから、ストリームデータをフロントエンドに送信して、フロントエンドがPDFファイルにアクセスできるようにする必要があります。
私はそれを次のように扱います:次のマッピングを作成します
@RequestMapping(value = "/pdfStreamHandler")
public void getRemoteFile(String urlPath, HttpServletResponse response) {
InputStream inputStream = null;
try {
try {
String strUrl = urlPath.trim();
URL url = new URL(strUrl);
//打开请求连接
URLConnection connection = url.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
httpURLConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
// 取得输入流,并使用Reader读取
inputStream = httpURLConnection.getInputStream();
/**
* 以上的操作处理是处理文件流的,如果访问的是远程PDF文件
* 可以直接new File("文件路径"),然后传给inputStream,
* 然后以下操作不变。
*/
int bytesum = 0;
int byteread = 0;
byte[] buffer = new byte[1024];
// 清空response
response.reset();
// 设置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + new String("cbzm.pdf".getBytes()));
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
bytesum = 0;
byteread = 0;
buffer = new byte[1024];
while ((byteread = inputStream.read(buffer)) != -1) {
bytesum += byteread;
toClient.write(buffer, 0, byteread);
}
toClient.flush();
inputStream.close();
toClient.close();
} catch (IOException e) {
e.printStackTrace();
inputStream = null;
}
} catch (Exception e) {
e.printStackTrace();
inputStream = null;
}
}
- 呼び出し方法は次のとおりです。
<!-- 其实和上面的调用没什么区别,知识把file换成了urlPath,如果需要自定义参数名的话,可以修改viewer.html中getUrlParam("urlPath")这个方法的参数,起成自己喜欢的名字 -->
<!-- 因为viewer.html的调用方法很多,我就这这样子举例,如果说想研究的话,可以尝试其他方法是否可以调用 -->
<a href='../js/pdfjs-2.5.207-dist/web/viewer.html?urlPath=PDF路径即可'>点击预览</a>
- 参考記事:
- https://blog.csdn.net/wf001015/article/details/93307643?utm_medium=distribute.pc_relevant.none-task-blog-baidulandingword-2&spm=1001.2101.3001.4242
- https://blog.csdn.net/baby97/article/details/83410628
- https://www.cnblogs.com/best-coder/p/11550409.html