ファイルの種類を検出する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 のインストールと設定方法のグラフィックチュートリアル

推薦する

基本構造、ドキュメント タイプ、ヘッダー、本文などの一般的な HTML 要素の概要。

1. 基本構造:コードをコピーコードは次のとおりです。 <!DOCTYPE html PUBL...

10 種類のモダンなレイアウトを実現するための CSS コード

序文日曜日に自宅で web.dev の 2020 3 日間ライブを視聴したところ、興味深い点がたくさ...

CSS3でシャトル星空のアニメーションを実現

結果: html <canvas id="スターフィールド"><...

純粋なJSを使用してセカンダリメニュー効果を実現します

この記事の例では、セカンダリメニュー効果を実現するためのJSの具体的なコードを参考までに共有していま...

JSブラウザストレージの詳しい説明

目次導入クッキークッキーとはクッキー生成方法クッキーの適用シナリオクッキーのデメリット回避策ローカル...

Linux での Makefile の書き方と使い方の詳細な説明

目次メイクファイルMakefile の命名とルールMakefile の仕組みMakefile変数Ma...

Win2008 R2 mysql 5.5 zip 形式 mysql のインストールと設定

Win2008 R2 zip形式のMySQLのインストールと設定1. Baidu MySQL 5.6...

Vue ライフサイクルの紹介とフック関数の詳細な説明

目次Vueライフサイクルの紹介とフック機能VUEライフサイクルフックVue ライフサイクルの紹介作成...

Dreamweaver8を使用してウェブサイトのファイルをチェックして整理する方法

Dreamweaver8 を使用して独自の Web サイトを作成する目的は何ですか?インターネットに...

MySQL のインデックスにおける NULL の影響についての詳細な説明

序文私は多くのブログを読み、弊社の DBA を含む多くの人々が、MySql では列に null が含...

...

React Native の基本原則の深い理解 (Bridge of React Native)

この記事では、React Native の基本をすでに理解していることを前提とし、ネイティブと Ja...

TypeScript のマップされた型とより優れたリテラル型推論について説明します。

目次概要マップされた型を使用して Object.freeze() を構築するマッピングタイプの構文は...