👩‍💻

#100 Vue 3でBlobを使ってみた

に公開

はじめに

Vue 3でBlobを使用する機会があったので記事にしました。
Blobの使用に伴い、CSP(コンテンツセキュリティポリシー)の設定を変更しなければならない場合があったため、CSPについても触れていきたいと思います。

Blob(Binary Large Object)とは

Blobは、ブラウザ内で画像、音声、動画、テキストなどバイナリデータを扱うことができるオブジェクトです。サーバーとの通信を行わずメモリ上で、ファイルのようにデータを保持・操作することができます。

Vue 3でのBlobを使ってみる

画像ファイルをアップロードして表示する

Blobを使って画像ファイルをアップロード、プレビュー表示させてみます。

<template>
  <div>
    <!-- ファイル選択用 -->
    <input type="file" @change="onFileChange" />
    
    <!-- 画像URLが存在する場合、画像を表示する -->
    <img v-if="imageUrl" :src="imageUrl" alt="Uploaded Image" />
    
    <!-- 画像が存在する場合、削除ボタンを表示する -->
    <button v-if="imageUrl" @click="removeImage">削除</button>
  </div>
</template>

<script>
import { ref, watch } from 'vue';

export default {
  setup() {
    const imageUrl = ref(null);

    // ファイル選択時に実行
    const onFileChange = (event) => {
      const file = event.target.files[0]; // 選択されたファイルを取得
      if (file) {
        const reader = new FileReader(); // FileReaderのインスタンスを作成
        reader.onload = (e) => {
          // 読み込み完了時にURLを生成してimageUrlに設定
          imageUrl.value = URL.createObjectURL(new Blob([e.target.result], { type: file.type }));
        };
        reader.onerror = (error) => {
          console.error("ファイルが読み込めません", error);
        };
        reader.readAsArrayBuffer(file);
      }
    };

    // 画像削除時に実行
    const removeImage = () => {
      if (imageUrl.value) {
        URL.revokeObjectURL(imageUrl.value); // 使わなくなったURLを解放する
      }
      imageUrl.value = null; // 画像URLをリセット
    };

    // 画像URLに変更があったとき実行
    watch(imageUrl, (newUrl, oldUrl) => {
      if (oldUrl) {
        URL.revokeObjectURL(oldUrl); // 使わなくなったURLを解放
      }
    });

    return { imageUrl, onFileChange, removeImage }; // テンプレートで使用するデータとメソッドを返す
  }
};
</script>

↓ 画像ファイル選択前

↓ 画像ファイル選択後

実際の画面はこのような動きです。

WEBアプリでBlobを使用する際の注意点

WEBアプリのセキュリティが厳しい場合、Blob URLがブロックされることがあります。
Blob URLを使って画像やファイルをブラウザで表示したりダウンロードしたりする場合は、CSPヘッダーで blob: を許可する必要があるからです。

CSP(Content Security Policy)とは

CSPは、Webアプリが外部リソースを安全に読み込のセキュリティ対策です。信頼できるソースからのリソースのみを許可して、XSS(クロスサイトスクリプティング)などの攻撃からアプリケーションを守ることができます。

Blob使用時のCSPの設定

例えば下記のようにCSPヘッダーに blob: を追加しBlobの使用を許可します。

http
Content-Security-Policy: default-src 'self'; img-src 'self' blob:; script-src 'self' 'unsafe-inline';

説明

default-src 'self'

デフォルトのリソースの読み込み元を自分自身のドメインに限定します。

img-src 'self' blob:

画像のソースに自分自身のドメインとBlob URLを使用できます。

script-src 'self' 'unsafe-inline

スクリプトのソースに自分自身のドメインとインラインスクリプトを使用できます。

他にも設定項目があるので、アプリの用途に合ったセキュリティ設定にしてください。

ブラウザからCSP設定を確認する

該当のページで開発者ツールを開き、「Network」タブでリソースを読み込んでいるリクエストを選択します。
リクエストの「Headers」>「Response Headers」から、Content-Security-Policy ヘッダーを確認することができます。

エラーが起きた時

CSPのエラーは開発者ツールのコンソールに表示されます。
既述したように、Blob URLの使用を許可するためには、img-src や media-src に blob: を追加する必要があります。
セキュリティ面を考慮しつつ必要なリソースの読み込みができるよう、CSP設定を見直しましょう。

まとめ

今後もBlobを使った操作やSCPについて理解を深めていきたいです。
ご覧いただきありがとうございました。

出典:
https://developer.mozilla.org/en-US/docs/Web/API/Blob
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

Discussion