ファイルの種類を検出するJavaScriptメソッド

ファイルの種類を検出するJavaScriptメソッド

入力要素の accept 属性を使用して、アップロードされるファイルの種類を制限することが考えられます。

<input type="file" id="inputFile" accept="image/png" />

このソリューションはほとんどのシナリオに対応できますが、ユーザーが JPEG 形式の画像のサフィックスを .png に変更すると、この制限をうまく克服できます。では、この問題はどのように解決すべきでしょうか?実際、ファイルのバイナリ データを読み取ることで正しいファイル タイプを識別できます。具体的な実施計画を紹介する前に、アバオ兄弟はまず画像タイプのファイルを例に、関連する知識を紹介します。

1. 画像のバイナリデータを表示する方法

画像に対応するバイナリ データを表示するには、Windows プラットフォームの WinHex や macOS プラットフォームの Synalyze It! Pro 16 進エディターなどの既製のエディターを使用できます。ここでは、Synalyze It! Pro エディターを使用して、Abao Ge のアバターに対応するバイナリ データを 16 進形式で表示します。

2. 絵の種類の見分け方

コンピュータは、画像サフィックスではなく、「マジックナンバー」によって異なるタイプの画像を区別します。 一部の種類のファイルでは、最初の数バイトの内容が固定されており、これらのバイトの内容に基づいてファイルの種類を判別できます。

一般的な画像タイプに対応するマジックナンバーを次の表に示します。

ファイルタイプファイルサフィックスマジックナンバー
JPEG jpg/jpeg 0xFF D8 FF
PNG png 0x89 50 4E 47 0D 0A 1A 0A
画像ギフ0x47 49 46 38 (GIF8)
BMPビットマップ0x42 4D

Synalyze It! Pro を使用して、Abao のアバター (abao.png) のタイプが正しいことを確認します。

上図からわかるように、PNG タイプの画像の最初の 8 バイトは 0x89 50 4E 47 0D 0A 1A 0A です。 abao.png ファイルを abao.jpeg に変更し、エディターを使用してイメージのバイナリ コンテンツを表示すると、ファイルの最初の 8 バイトは変更されていないことがわかります。ただし、input[type="file"]入力ボックスを使用してファイル情報を読み取ると、次の結果が出力されます。

当然のことながら、ファイル拡張子やファイルの MIME タイプでは正しいファイル タイプを識別することはできません。次に、アバオ兄弟は、画像をアップロードするときに画像のバイナリ情報を読み取って、正しい画像タイプを確認する方法を紹介します。

3. 画像の種類を検出する方法

3.1 readBuffer関数を定義する

ファイル オブジェクトを取得したら、FileReader API を通じてファイルの内容を読み取ることができます。ファイルの完全な情報を読み取る必要はないため、Abaoge は readBuffer 関数をカプセル化して、ファイル内の指定された範囲のバイナリ データを読み取ります。

関数 readBuffer(ファイル、開始 = 0、終了 = 2) {
  新しい Promise を返します ((resolve, reject) => {
    const リーダー = 新しい FileReader();
    リーダー.onload = () => {
      解決します(reader.result);
    };
    reader.onerror = 拒否;
    reader.readAsArrayBuffer(file.slice(start, end));
  });
}

PNG タイプの画像の場合、ファイルの最初の 8 バイトは 0x89 50 4E 47 0D 0A 1A 0A です。したがって、選択したファイルが PNG タイプの画像であるかどうかを検出するときは、最初の 8 バイトのデータを読み取り、各バイトの内容が 1 つずつ一貫しているかどうかを判断するだけで済みます。

3.2 チェック機能の定義

バイト単位の比較と再利用の向上を実現するために、Abaoge はチェック関数を定義します。

関数チェック(ヘッダー) {
  戻り値 (バッファ、オプション = { オフセット: 0 }) =>
    ヘッダー.every(
      (ヘッダー、インデックス) => ヘッダー === バッファ[options.offset + インデックス]
    );
}

3.3 PNG画像タイプの検出

上記で定義した readBuffer 関数と check 関数に基づいて、PNG 画像を検出する機能を実装できます。

3.3.1 HTMLコード

<div>
   ファイルを選択: <input type="file" id="inputFile" accept="image/*"
              onchange="handleChange(イベント)" />
   <p id="実際のファイルタイプ"></p>
</div>

3.3.2 JSコード

const isPNG = check([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); // PNG 画像に対応するマジックナンバー const realFileElement = document.querySelector("#realFileType");

非同期関数handleChange(イベント) {
  定数ファイル = event.target.files[0];
  const buffers = readBuffer(file, 0, 8) を待機します。
  const uint8Array = 新しい Uint8Array(バッファ);
  realFileElement.innerText = `${file.name}ファイルの種類は次のとおりです: ${
    isPNG(uint8Array) ? "image/png" : ファイルタイプ
  }`;
}

上記の例が正常に実行されると、対応する検出結果が次の図に表示されます。

上の図からわかるように、正しい画像形式を正常に検出できます。 JPEG ファイル形式を検出する場合は、isJPEG 関数を定義するだけです。

定数isJPEG = チェック([0xff, 0xd8, 0xff])

しかし、PDF ファイルなど他の種類のファイルを検出したい場合はどうすればよいでしょうか?ここではまず、Synalyze It! Pro エディターを使用して PDF ファイルのバイナリ コンテンツを参照します。

上の図から、PDF ファイルの最初の 4 バイトは 0x25 50 44 46 であり、対応する文字列は %PDF であることがわかります。ユーザーが検出の種類をより直感的に識別できるようにするために、Abaoge は stringToBytes 関数を定義します。

関数 stringToBytes(文字列) {
  [...文字列].map((文字) => character.charCodeAt(0)); を返します。
}

stringToBytes 関数に基づいて、次のように isPDF 関数を簡単に定義できます。

const isPDF = check(stringToBytes("%PDF"));

isPDF 関数を使用すると、PDF ファイル検出機能を実装できます。しかし、実際の作業では、遭遇するファイルの種類は多岐にわたります。この場合、ファイルタイプライブラリなどの既製のサードパーティライブラリを使用して、ファイル検出機能を実装できます。

実際、ファイルのバイナリデータに基づいて、ファイルの種類を検出するだけでなく、画像サイズ、ビット深度、色の種類、圧縮アルゴリズムなどのファイル関連のメタ情報も読み取ることができます。実際の状況を確認するために、引き続きAbaoのアバター(abao.png)を例に挙げてみましょう。

さて、フロントエンドでファイルの種類を検出する方法については以上です。実際のプロジェクトでは、ファイルのアップロード シナリオでは、セキュリティ上の理由から、開発プロセス中にアップロードするファイルの種類を制限することをお勧めします。より厳密なシナリオでは、Abao が導入した方法を使用してファイルの種類を確認することを検討できます。

上記は、JavaScript がファイルの種類を検出する仕組みの詳細です。JavaScript がファイルの種類を検出する仕組みの詳細については、123WORDPRESS.COM の他の関連記事をご覧ください。

以下もご興味があるかもしれません:
  • JavaScript 型検出方法の例のチュートリアル
  • JS配列インデックス検出におけるデータ型の問題の詳細な説明
  • JavaScript のデータ型とデータ型の検出方法の詳細な説明
  • JavaScript におけるデータ型検出方法の詳細な説明
  • jsデータ型検出の概要
  • js学習まとめ_データ型検出に基づく4つの方法(必読)
  • 配列型を検出するためのJSメソッドの概要
  • JavaScript でデータ型を検出するいくつかの方法の概要
  • JavaScript の基本データ型と一般的な型検出方法の概要
  • JS でデータ型を検出するいくつかの方法とその長所と短所のまとめ
  • さまざまな数値型の JS 正規表現マッチング検出 (デジタル検証)
  • さまざまな種類のJavaScriptを検出する方法
  • JavaScript の型検出: typeof と instanceof の欠陥と最適化
  • JavaScript 学習ノート: クライアントの種類 (エンジン、ブラウザ、プラットフォーム、オペレーティング システム、モバイル デバイス) の検出
  • Javascriptはクライアントタイプのコードパッケージの検出を実装します

<<:  Docker プライベート サーバー イメージを定期的にクリーンアップする方法

>>:  MySQL Community Server 8.0.12 のインストールと設定方法のグラフィックチュートリアル

推薦する

Vue のスロットの使用法と適用シナリオの詳細な分析

スロットとは何ですか? Vue では、子コンポーネント タグの中央に何もラップできないことはわかって...

mysql5.7 リモート アクセス設定

mysql5.7 でリモート アクセスを設定することは、ユーザーを作成して権限を付与するだけでアクセ...

Linux でプロセスを隠す方法と、遭遇する落とし穴

序文1. この記事で使用したツールは、https://github.com/gianlucabore...

Linux ssh サーバーの構成コード例

LinuxホストにSSHサーバーをインストールするには、次のターミナルコマンドを使用します: sud...

MyBatis 動的 SQL の包括的な説明

目次序文動的SQL 1. まずモジュールのディレクトリ構造を見てみましょう2. 物理モデリングと論理...

MySQL データベース アカウントの作成、認証、データのエクスポートおよびインポート操作の例

この記事では、MySQL データベースでのアカウントの作成、認証、データのエクスポートおよびインポー...

Tomcat でのコネクタ構成

JBoss は Tomcat を Web コンテナとして使用するため、JBoss の Web コンテ...

mysqlのkey_lenの計算方法についての簡単な説明

MySQL の explain コマンドは SQL のパフォーマンスを分析できます。その 1 つが ...

Dockerは異常なコンテナ操作を排除する

この初心者は、Docker を学び始めたばかりの頃にこのような問題に遭遇しました。記録しておきます。...

HTML と CSS を書くための 6 つの最も効果的な方法

この記事では、効率を向上させ、時間を節約することを願って、最も効果的な 6 つの方法を紹介します。 ...

JSはUUIDとNanoIDというユニークなIDメソッドを生成します

目次1. NanoIDがUUIDに取って代わる理由2. jsを生成する方法3. ナノID方式序文:ユ...

効率を向上できる Linux コマンドエイリアス 10 個のまとめ

序文Linux 環境で作業するエンジニアは、これらの面倒な命令とパラメータのコマンドラインにきっと驚...

エラー 1862 (HY000): パスワードの有効期限が切れています。ログインするには、..... を使用してパスワードを変更する必要があります。

エラーメッセージ:エラー 1862 (HY000): パスワードの有効期限が切れています。ログインす...

3次元画像配置効果を実現する純粋なCSSのサンプルコード

1. 要素の幅/高さ/パディング/マージンのパーセンテージ基準要素の幅/高さ/パディング/マージンの...

HTML/CSS の基礎 - HTML コード記述におけるいくつかの注意事項 (必読)

この記事の警告事項は、ブラウザの互換性とはまったく関係ありません。主に、プロジェクトで遭遇したいくつ...