私はウェブアプリケーションを持っています。Google Chrome で実行され、他のブラウザーで動作する必要はありません。
サーバーで生成され、AJAX 要求でクライアントに送り返された PDF データがあります。PDF データからブロブを作成します。window.URL.createObjectURL を使用して blob から URL を作成し、それを PDF を表示するために以前に作成したウィンドウ (私の preview_window) に読み込みます。
URL を読み込むために、preview_window.location.href を設定します。
新しい PDF が生成されてウィンドウでプレビューされるたびにリソースが無駄になるのを避けるために、revokeObjectURL を呼び出したいと思います。問題は、preview_window.location.href を設定した直後に呼び出すのが早すぎて、PDF が表示されなくなることです。そのため、URL が読み込まれた後にのみ revokeObjectURL を呼び出したいと思います。この目的で preview_window.onload をコールバックに設定しようとしましたが、呼び出されません。
私が知りたいのですが:
- 私がやろうとしているように、ウィンドウが URL をロードしたときにコールバックをトリガーすることは可能ですか? どのように?
- revokeObjectURL がタイムリーに呼び出されるようにする別の方法はありますか?
ウィンドウが URL の読み込みを完了したときに revokeObjectURL をトリガーできない場合は、新しい URL を生成する直前に各 URL を取り消すことができます。しかし、可能であれば、読み込みが完了したらすぐに URL を取り消したいと思います。
状況をよく示す html ファイルを用意しました。
<html>
<head>
<title>Show PDF Demo</title>
<script>
var build_blob = function(mime_type, data) {
var buf = new ArrayBuffer(data.length);
var ia = new Uint8Array(buf);
for (var i = 0; i < data.length; i++) ia[i] = data.charCodeAt(i);
var blob = new Blob([ buf ], { type: mime_type });
return blob;
};
window.onload = function(e) {
document.getElementById('preview_button').onclick = function(e) {
// open the window in the onclick handler so we don't trigger popup blocking
var preview_window = window.open(null, 'preview_window');
// use setTimeout to simulate an asynchronous AJAX request
setTimeout(function(e) {
var pdf_data = atob(
"JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZwovT3V0bGluZXMgMiAwIFIKL1BhZ2Vz" +
"IDMgMCBSCj4+CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9PdXRsaW5lcwovQ291bnQgMAo+Pgpl" +
"bmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMKL0tpZHMgWzQgMCBSXQovQ291bnQgMQo+Pgpl" +
"bmRvYmoKNCAwIG9iago8PCAvVHlwZSAvUGFnZQovUGFyZW50IDMgMCBSCi9NZWRpYUJveCBbMCAw" +
"IDUwMCAyMDBdCi9Db250ZW50cyA1IDAgUgovUmVzb3VyY2VzIDw8IC9Qcm9jU2V0IDYgMCBSCi9G" +
"b250IDw8IC9GMSA3IDAgUiA+Pgo+Pgo+PgplbmRvYmoKNSAwIG9iago8PCAvTGVuZ3RoIDczID4+" +
"CnN0cmVhbQpCVAovRjEgMjQgVGYKMTAwIDEwMCBUZAooU01BTEwgVEVTVCBQREYgRklMRSkgVGoK" +
"RVQKZW5kc3RyZWFtCmVuZG9iago2IDAgb2JqClsvUERGIC9UZXh0XQplbmRvYmoKNyAwIG9iago8" +
"PCAvVHlwZSAvRm9udAovU3VidHlwZSAvVHlwZTEKL05hbWUgL0YxCi9CYXNlRm9udCAvSGVsdmV0" +
"aWNhCi9FbmNvZGluZyAvTWFjUm9tYW5FbmNvZGluZwo+PgplbmRvYmoKeHJlZgowIDgKMDAwMDAw" +
"MDAwMCA2NTUzNSBmCjAwMDAwMDAwMDkgMDAwMDAgbgowMDAwMDAwMDc0IDAwMDAwIG4KMDAwMDAw" +
"MDEyMCAwMDAwMCBuCjAwMDAwMDAxNzkgMDAwMDAgbgowMDAwMDAwMzY0IDAwMDAwIG4KMDAwMDAw" +
"MDQ2NiAwMDAwMCBuCjAwMDAwMDA0OTYgMDAwMDAgbgp0cmFpbGVyCjw8IC9TaXplIDgKL1Jvb3Qg" +
"MSAwIFIKPj4Kc3RhcnR4cmVmCjYyNQolJUVPRg=="
);
/*
Warning: for my Chrome (Version 44.0.2403.155 m), the in-built PDF viewer doesn't seem
to work with a blob when this html page is loaded from the local filesystem. I have only
got this to work when fetching this page via HTTP.
*/
var pdf_blob = build_blob('application/pdf', pdf_data);
var pdf_url = window.URL.createObjectURL(pdf_blob);
preview_window.onload = function(e) {
console.log("preview_window.onload called"); // never happens
window.URL.revokeObjectURL(pdf_url);
};
preview_window.location.href = pdf_url;
console.log("preview_window.location.href set");
}, 500);
};
};
</script>
</head>
<body>
<button id="preview_button">Show Preview</button>
</body>
</html>
上記のデモ コードではそれを回避していますが、アプリケーション用に jQuery をロードしています。
検索でこの質問を見つけましたが、その状況ではメインウィンドウ(「ウィンドウ」)が新しいURLを指しており、ウィンドウがウィンドウから来た場合に違いがあるかどうかをコメントで尋ねると、OPは応答を受け取りませんでした。開いた。