ファイルの種類を検出する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)

HTML フォームは、さまざまな種類のユーザー入力を収集するために使用されます。 HTML フォー...

DockerイントラネットはDNSを構築し、ip:port操作の代わりにドメイン名アクセスを使用します

たとえば、イントラネットに Jenkins サーバーがある場合、そのサーバーにアクセスするには、その...

divの適応高さは残りの高さを自動的に埋めます

シナリオ 1: HTML: <div class="outer"> ...

フロントエンド制作に関する簡単な議論: 互換性のために IE6 はまだ必要ですか?

国内市場ではIE6~7のサポートに対する一定の需要がまだありますが、フロントエンド開発者として、私た...

ゲーム着物メモ問題の簡単な分析

本日、ゲームを再起動した後、バックアップしたデータをターゲットデータベースにインポートできないことが...

HTML と CSS に関する基本的なメモ (フロントエンドでは必読)

HTMLに触れた当初はレイアウトにいつもテーブルを使っていましたが、とても面倒で見た目も悪かったの...

Webリクエストと処理のTomcatソースコード分析

目次序文1. エンドポイント2. 接続ハンドラ3. コヨーテ4. コンテナ責任チェーンパターン序文T...

純粋な HTML ページを送信し、パラメータを渡し、ID を確認する方法

プロジェクトにはアンケートが必要ですが、クライアントはアンケートのタイトルが純粋なHTMLタグでなけ...

Docker 経由で Redis 6.x クラスターをデプロイする方法

システム環境: Redis バージョン: 6.0.8 Docker バージョン: 19.03.12シ...

ウェブサイトのパフォーマンス: 画像とCookieの最適化、モバイルアプリケーションの最適化

前のセクションでは、コンテンツ、サーバー、JavaScript、CSS など、Web サイトのパフォ...

JavaScriptにおけるPromiseの使い方と注意点について(推奨)

1. 約束の説明Promise は、非同期操作の最終状態 (失敗または正常完了) とその結果の値を...

DockerにRocketMQをインストールするための実装手順

目次1. 画像を取得する2. ブローカーサーバーを作成する3. ブローカーを作成する4. Rocke...

イメージのパッケージ化とワンクリック展開を実現するためにDockerを組み合わせたアイデア

1. サーバーにDockerをインストールする yumでdockerをインストール設定ファイルを変更...

Mysql5.7 で中国語の文字化けの問題を解決する

MySQL 5.7 を使用すると、Web ターミナル経由でデータベースに中国語の文字を書き込むと文字...

js クロージャとガベージ コレクション メカニズムの例の詳細な説明

目次序文文章1. 終了1.1 クロージャとは何ですか? 1.2 クロージャの特性1.3 クロージャを...