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

推薦する

Linux(中心OS7)は、Java Webプロジェクトの実行環境を構築するためにJDK、Tomcat、MySQLをインストールします。

1. JDKをインストールする1. 古いバージョンまたはシステム独自のJDKをアンインストールする...

MySQL 時間統計方法の概要

データベースの統計を行う場合、多くの場合、年、月、日に基づいてデータを収集し、echart を使用し...

ウェブページに埋め込まれた Flash と IE、FF、Maxthon の互換性の問題

いろいろ苦労した後、インターネットで検索したり、以前の会社のプロジェクトを探したり、他の人のプロジェ...

フォームの「Enter」、「Submit」、「Enter != Submit」を削除する方法

「Enter != Submit」問題を実装するには、通常、「ボタンの種類」と「入力ボックスの数」か...

カルーセル効果を実現するネイティブJavaScript

この記事では、カルーセルの効果を実現するためのJavaScriptの具体的なコードを参考までに共有し...

Ubuntuデュアルシステムが起動時に停止する問題の解決方法の詳細な説明

起動時に Ubuntu デュアル システムが停止する問題の解決方法 (Ubuntu 16.04 およ...

html-cssタグのスタイル設定が機能しない2つの理由

1 セミコロン「;」のない CSS スタイル2 タグが閉じられておらず、「>」がありません...

CSSアニメーションがJSによってブロックされるかどうかについての簡単な議論

CSS のアニメーション部分は JS によってブロックされますが、transform のアニメーショ...

トランザクション分離レベルのMySQLケース分析

目次1. 理論シリアル化可能繰り返し読み取りコミットされた読み取りコミットされていない読み取り2. ...

Linux で 1 つのファイルの内容を別のファイルの末尾にコピーする

問題の説明:たとえば、ファイル 11 の内容は次のとおりです。こんにちはファイル22の内容は次のとお...

MySQLの自己接続と結合の詳細な理解

1. MySQL 自己接続MySQL では、情報を照会するときに自分自身に接続 (自己接続) する必...

MySQL の問題を解決する: MSVCR120.dll が見つからないため、コードの実行を続行できません

1. 問題MySQL の初期化時に発生する問題は、次のとおりです。 1. 「MSVCR120.dll...

W3Cチュートリアル(16):その他のW3Cの活動

このセクションでは、その他の重要かつ興味深い W3C アクティビティの概要を説明します。このセクショ...

border-radiusは要素に丸い境界線を追加する方法です

border-radius:10px; /* すべての角は半径 10px で丸められます*/ bor...

Linux クラウド サーバー上に SFTP サーバーとイメージ サーバーを構築する方法

まず、SFTP プロトコルと FTP プロトコルの違いを理解してください。ここでは詳細には触れません...