1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Posted at

はじめに

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

Blob(Binary Large Object)とは

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

Vue 3でのBlobを使ってみる

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

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

vue
<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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?