JavaScriptでFetch APIを使用して、画像やPDFを取得した後にブラウザに表示する方法について書いています。
簡単なサンプルコードを用意して試してみました。
Fetch APIでファイルを取得した後にwindow.openを使用して、新規ウィンドウで開いてみています。
画像の方は、HTMLにimgタグで追加しての表示もやってみました。
ブラウザにはGoogle Chromeを使用しています。
FetchAPIの参考記事:Fetch APIの使い方(JavaScriptでHTTP通信)
今回使用するAPIのバックエンドの実装
バックエンドはLaravelで実装していて、下記のように返しています。
それぞれStorage
を使用してファイルを取得して、レスポンスで返しています。
public function fetchImageBinary() {
$image = Storage::get('test.png');
return response($image, 200, ['Content-Type' => 'image/png']);
}
public function fetchPdfBinary() {
$pdf = Storage::get('test.pdf');
return response($pdf, 200, ['Content-Type' => 'application/pdf; charset=utf-8']);
}
fetchImageBinary
で画像ファイルを、画像のContent-Type
をつけて返しています。
fetchPdfBinary
ではPDFファイルを同じように、PDFのContent-Type
をつけて返しています。
それぞれ、JavaScriptで呼び出して、ブラウザの新規ウィンドウで表示します。
画像を取得して、新規ウィンドウで開く
openBlobImage
という関数を用意して、画像を取得した後にwindow.open
で開いてみました。
この関数は画面からボタンを押したときに動きます。
function openBlobImage() {
fetch("http://127.0.0.1:8000/api/image/test_binary").then(response => {
response.blob().then(blobResponse => {
const fileUrl = URL.createObjectURL(blobResponse)
window.open(fileUrl)
})
})
}
画像を返すAPI
にfetch
でアクセスして、結果をresponse
で受けています。
response
はResponse
オブジェクトです。
response
からblob
メソッドを呼ぶことで、画像のBlob
オブジェクトを取得できます。
取得したBlob
オブジェクトがblobResponse
に入っています。
Blob
オブジェクトをURL.createObjectURL
に渡すことで、オブジェクトのURLを作成してくれます。
このURLの期限は呼び出したHTMLのタブが閉じられるまでです。
取得したURL(fileUrl
)をwindow.open
で開いています。
結果、下記のように新しいウィンドウで画像が表示されます。
画像を取得して、imgタグで表示する
同じようにshowBlobImage
という関数を用意して、画像を取得した後にimg
タグでHTML要素に追加してみました。
この関数も画面からボタンを押したときに動きます。
function showBlobImage() {
fetch("http://127.0.0.1:8000/api/image/test_binary").then(response => {
response.blob().then(blobResponse => {
const fileUrl = URL.createObjectURL(blobResponse)
document.querySelector('#image_result').innerHTML = `<img src='${fileUrl}' />`
})
})
}
先ほどと同じようにfetch
でAPI
にアクセスして、Blob
オブジェクトで取得した後にcreateObjectURL
でURLを作成しています。
作成したURLをimg
タグのsrc
属性に指定することにより表示することが可能です。
結果、下記のように表示されます。
PDFを取得して、新規ウィンドウで開く
最後にPDFをfetchして、ブラウザの新規ウィンドウで表示してみました。
PDFをレスポンスで返すAPIにfetch
でアクセスしています。
function openBlobPdf() {
fetch("http://127.0.0.1:8000/api/image/test_pdf").then(response => {
response.blob().then(blobResponse => {
const fileUrl = URL.createObjectURL(blobResponse)
window.open(fileUrl)
})
})
}
先ほどと同様にして、Response
オブジェクトを取得した後にblob
メソッドを呼び出しています。
取得したPDFのBlob
オブジェクト(blobResponse
)をcreateObjectURL
に渡してURLを作成します。
作成したURLをwindow.open
に渡すことによって、新規ウィンドウでPDFを開きます。
結果として、下記のように表示されます。
Fetch APIで取得したPDF・画像のサンプルコード
今回紹介したサンプルコード全文を載せておきます。
Bootstrap5で見栄えをいい感じにして、作成してみました。
Fetch APIのURLの箇所をそれぞれ書き換えてもらえると動くと思います。
<html>
<head>
<meta charset="UTF-8" />
<title>blob open test</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<script>
function openBlobImage() {
fetch("http://127.0.0.1:8000/api/image/test_binary").then(response => {
console.log(response)
response.blob().then(blobResponse => {
console.log(blobResponse)
const fileUrl = URL.createObjectURL(blobResponse)
window.open(fileUrl)
})
})
}
function openBlobPdf() {
fetch("http://127.0.0.1:8000/api/image/test_pdf").then(response => {
response.blob().then(blobResponse => {
const fileUrl = URL.createObjectURL(blobResponse)
window.open(fileUrl)
})
})
}
function showBlobImage() {
fetch("http://127.0.0.1:8000/api/image/test_binary").then(response => {
response.blob().then(blobResponse => {
const fileUrl = URL.createObjectURL(blobResponse)
document.querySelector('#image_result').innerHTML = `<img src='${fileUrl}' />`
})
})
}
</script>
<body>
<nav class="navbar navbar-light" style="background-color: #e3f2fd;">
<div class="container-fluid">
<a class="navbar-brand" href="#">Blob Open Test</a>
</div>
</nav>
<div class="container mt-5">
<button type="button" class="btn btn-success" onclick="openBlobPdf()">PDFを開く</button>
<button type="button" class="btn btn-success" onclick="openBlobImage()">画像を開く</button>
<button type="button" class="btn btn-success" onclick="showBlobImage()">画像を表示する</button>
<div id="image_result"></div>
</div>
</body>
</html>
コメント