入力要素の 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. 絵の種類の見分け方コンピュータは、画像サフィックスではなく、「マジックナンバー」によって異なるタイプの画像を区別します。 一部の種類のファイルでは、最初の数バイトの内容が固定されており、これらのバイトの内容に基づいてファイルの種類を判別できます。 一般的な画像タイプに対応するマジックナンバーを次の表に示します。
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 の他の関連記事をご覧ください。 以下もご興味があるかもしれません:
|
<<: Docker プライベート サーバー イメージを定期的にクリーンアップする方法
>>: MySQL Community Server 8.0.12 のインストールと設定方法のグラフィックチュートリアル
HTML フォームは、さまざまな種類のユーザー入力を収集するために使用されます。 HTML フォー...
たとえば、イントラネットに Jenkins サーバーがある場合、そのサーバーにアクセスするには、その...
シナリオ 1: HTML: <div class="outer"> ...
国内市場ではIE6~7のサポートに対する一定の需要がまだありますが、フロントエンド開発者として、私た...
本日、ゲームを再起動した後、バックアップしたデータをターゲットデータベースにインポートできないことが...
HTMLに触れた当初はレイアウトにいつもテーブルを使っていましたが、とても面倒で見た目も悪かったの...
目次序文1. エンドポイント2. 接続ハンドラ3. コヨーテ4. コンテナ責任チェーンパターン序文T...
プロジェクトにはアンケートが必要ですが、クライアントはアンケートのタイトルが純粋なHTMLタグでなけ...
システム環境: Redis バージョン: 6.0.8 Docker バージョン: 19.03.12シ...
前のセクションでは、コンテンツ、サーバー、JavaScript、CSS など、Web サイトのパフォ...
1. 約束の説明Promise は、非同期操作の最終状態 (失敗または正常完了) とその結果の値を...
目次1. 画像を取得する2. ブローカーサーバーを作成する3. ブローカーを作成する4. Rocke...
1. サーバーにDockerをインストールする yumでdockerをインストール設定ファイルを変更...
MySQL 5.7 を使用すると、Web ターミナル経由でデータベースに中国語の文字を書き込むと文字...
目次序文文章1. 終了1.1 クロージャとは何ですか? 1.2 クロージャの特性1.3 クロージャを...