VueアプリでPDFブロブとして受け取り、ブラウザのPDFビューアーを使用して表示したい。
ファイルに変換し、オブジェクトのURLを生成します。
const blobFile = new File([blob], `my-file-name.pdf`, { type: 'application/pdf' })
this.invoiceUrl = window.URL.createObjectURL(blobFile)
次に、そのURLをオブジェクト要素のdata
属性として設定して表示します。
<object
:data="invoiceUrl"
type="application/pdf"
width="100%"
style="height: 100vh;">
</object>
ブラウザは、PDFビューアを使用してPDFを表示します。ただし、Chromeでは、提供するファイル名(ここではmy-file-name.pdf )は使用されません:PDFビューアーのタイトルバーにハッシュが表示され、「右クリック->名前を付けて保存...」またはビューアーのコントロールを使用してファイルをダウンロードすると、blobのハッシュ(cda675a6-10af-42f3-aa68-8795aa8c377d
または類似)。
ビューアとファイル名は、Firefoxで期待したとおりに機能します。ファイル名が使用されていないのはChromeのみです。
ネイティブJavascript(ES6を含むが、Vue以外のサードパーティの依存関係はない)を使用して、Chromeのblob/object要素のファイル名を設定する方法はありますか?
[編集]役立つ場合、応答には次の関連ヘッダーがあります。
Content-Type: application/pdf; charset=utf-8
Transfer-Encoding: chunked
Content-Disposition: attachment; filename*=utf-8''Invoice%2016246.pdf;
Content-Description: File Transfer
Content-Encoding: gzip
Chromeの拡張機能は、URIに設定されているリソース名、つまりfile.ext
in protocol://domain/path/file.ext
。
したがって、元のURIにそのファイル名が含まれている場合、最も簡単なのは、Blobの方法ではなく、PDFを直接取得したURIに<object>のdata
を作成することです。
今、それを行うことができない場合があり、これらのために、複雑な方法があります。これは、将来のChromeのバージョンでは動作しない可能性があり、おそらく他のブラウザでは動作しません Service Worker を設定する必要があります。
最初に言ったように、Chromeはファイル名を検索してURIを解析します。そのため、BlobURIを指すこのファイル名を持つURIを作成する必要があります。
そしてそれを可能にするために、私が今のところ見つけた唯一の方法は、
src
を設定します1 その偽のURIに。1。Chromeの<object>タグから行われたリクエストを確認できなかったため、ここでiframeを使用することをお勧めします(IEでも良い結果が得られます) 。
またはコードで、
document.html
// register our ServiceWorker
navigator.serviceWorker.register('/sw.js')
.then(...
...
function displayRenamedPDF(file, filename) {
// we use an hard-coded fake path
// that we will check in every requests from the SW
const reg_path = '/nameForcer_register/'
// pass the filename
const url = reg_path + encodeURIComponent(filename);
const xhr = new XMLHttpRequest();
xhr.open('POST', url);
return new Promise((res, rej) => {
xhr.onload = e => {
const frame = document.createElement('iframe');
frame.src = xhr.response;
document.body.append(frame);
return frame;
};
xhr.send(file);
})
}
ServiceWorkerでsw.js
self.addEventListener('fetch', function(event) {
const req = event.request,
url = new URL(req.url),
// parse the /path/ from every request url
pathes = url.pathname.split('/'),
// are we registering
nameRegIndex = pathes.indexOf('nameForcer_register'),
// or fetching
nameFetcherIndex = pathes.indexOf('nameForcer_fetch');
if(nameRegIndex > -1) { // register
event.respondWith(
req.blob() // grab the POSTed Blob
.then((blob) => {
const filename = pathes[nameRegIndex+1] || '';
// store in our db object
db[filename] = blob;
return filename;
})
.then((filename) =>
new Response('/nameForcer_fetch/' + filename)
)
);
}
else if(nameFetcherIndex > -1) { // fetch
const filename = pathes[nameFetcherIndex + 1];
const cached = db[filename];
// just for Firefox, Chrome doesn't care...
const headers = new Headers({
'Content-Disposition': 'inline; filename="' + decodeURIComponent(filename) + '"'
});
event.respondWith(
new Response(cached, {
headers: headers
})
);
delete db[filename]; // !! one time URI !!
}
else { // normal requests
event.respondWith(fetch(event.request))
}
});
残念ながら、plnkr.coでServiceWorkerを動作させることはできませんでしたが、ローカルホストにコピーできるはずの ここにセットアップ 全体を見つけることができます。
また、他の解決策として、自分で確認するのに時間をかけなかったので、独自のpdfビューアーを実行することになるでしょう。
Mozillaはjsベースのプラグイン pdf.js を利用可能にしているので、そこからファイル名を設定できるはずです(もう一度掘り下げていませんが)。
最後に、FirefoxはblobURIが指すname
オブジェクトのFile
プロパティを使用できます。だから、それはOPが要求したものではありませんが、FFでそれが必要なのは
const file = new File([blob], filename);
const url = new URL(blob);
object.data = url;
独自のサーバー経由でリソースをリクエストしている場合は、Content-Disposition
応答でファイル名を渡す応答ヘッダー。
Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"
ファイル名と拡張子に置き換えることができます。あなたはこれを見ることができます link .
Chromeでは、ファイル名はURLから取得されるため、blob URLを使用している限り、短い答えは「いいえ、Chromeに表示されるPDFオブジェクトのファイル名を設定できません」です。 blob URLに割り当てられたUUIDを制御することはできず、object
要素を使用してページの名前としてそれをオーバーライドする方法もありません。 PDF内でタイトルが指定され、PDFビューアーにドキュメント名として表示される可能性がありますが、ダウンロード時にハッシュ名が取得されます。
これはセキュリティ上の予防策のように見えますが、確実に言うことはできません。
もちろん、URLを制御できる場合は、URLを変更してPDFファイル名を簡単に設定できます。