web-dev-qa-db-ja.com

<input type = "file">を使用するときのファイル形式を制限しますか?

ユーザーがHTMLの<input type="file">要素の[参照]ボタンをクリックしたときに、ネイティブOSのファイル選択機能から選択できるファイルの種類を制限したいです。不可能だと感じますが、解決策であるかどうかを知りたいのですが。 HTMLとJavaScriptだけにしておきたいのですが。フラッシュしないでください。

529
Bojangles

厳密に言えば、答えは no です。開発者cannotは、ネイティブOSのファイル選択ダイアログボックスで、ユーザーが任意の種類または拡張子のファイルを選択できないようにします。

それでも、<input type = "file">accept属性は、OSのファイル選択ダイアログボックスでフィルタを提供するのに役立ちます。例えば、

<!-- (IE 10+, Edge, Chrome, Firefox 42+) -->
<input type="file" accept=".xls,.xlsx" />

.xlsまたは.xlsx以外のファイルを除外する方法を提供する必要があります。 input要素の MDN ページは常にこれをサポートしていると言っていましたが、驚いたことに、これはFirefoxではバージョン42まではうまくいきませんでした。IE 10+で動作します。 Edge、そしてChrome。

そのため、42歳以上のFirefoxをIE 10+、Edge、Chrome、およびOperaと一緒にサポートするには、MIMEタイプのカンマ区切りのリストを使用することをお勧めします。

<!-- (IE 10+, Edge, Chrome, Firefox) -->
<input type="file"
 accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-Excel" /> 

[ Edge behavior:ファイルタイプフィルタのドロップダウンには、ここで説明したファイルタイプが表示されますが、ドロップダウンのデフォルトではありません。デフォルトのフィルタはAll files (*)です。]

MIMEタイプにアスタリスクを使用することもできます。例えば:

<input type="file" accept="image/*" /> <!-- all image types --> 
<input type="file" accept="audio/*" /> <!-- all audio types --> 
<input type="file" accept="video/*" /> <!-- all video types --> 

W3Caccept属性にMIMEタイプとそれに対応する拡張子の両方を指定することをauthorsに推奨します。したがって、 best アプローチは次のようになります。

<!-- Right approach: Use both file extensions and corresponding MIME-types. -->
<!-- (IE 10+, Edge, Chrome, Firefox) -->
<input type="file"
 accept=".xls,.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-Excel" /> 

同じのJSFiddle: ここ

参照: MIMEタイプの一覧

重要: accept属性を使用すると、目的のタイプのファイルをフィルタリングする方法しか提供されません。ブラウザでも、ユーザーは任意の種類のファイルを選択できます。追加の(クライアント側の)チェックを(JavaScriptを使用して、片方は this にする)、そして確実にファイルタイプサーバーで検証しなければならないを使用します。ファイル拡張子とそのバイナリ署名の両方を使用するMIMEタイプの組み合わせ( ASP.NETPHPRubyJava )。より堅牢なサーバー側の検証を実行するために、ファイルの種類とその マジックナンバー については thesetables を参照することをお勧めします。

これは、ファイルのアップロードとセキュリティに関する threegoodread です。

編集: HTML5ファイルAPIを使用して、バイナリ署名を使用したファイルタイプの確認をクライアントサイドでJavaScriptを使用して(単に拡張子を見ることではなく)実行することもできます。悪意のあるユーザーがカスタムHTTP要求を作成してファイルをアップロードできるようになるためです。

873
Sachin Joseph

入力タグにはaccept属性があります。しかし、それは決して信頼できません。ブラウザは、それを「提案」として扱う可能性が最も高いです。つまり、ファイルマネージャにもよりますが、ユーザーは希望する種類のみを表示する事前選択を行うことになります。それでも「すべてのファイル」を選択して、必要なファイルをアップロードできます。

例:

<form>
  <input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" />
</form>

html5の仕様をもっと読む

これは、ユーザーが正しいファイルを見つけるための「ヘルプ」としてのみ使用されることを覚えておいてください。すべてのユーザーが自分のサーバーに自分が望む要求を送信できます。あなたは常にすべてのサーバー側を検証する必要があります。

だから答えは:いいえあなた 制限することはできません しかし、あなた できる 事前選択を設定します - あなたは できない それに頼る。

その代わりにまたはそれに加えて、JavaScriptでファイル名(入力フィールドの値)をチェックすることによって同様のことを行うことができますが、これは保護を提供せず、またユーザーの選択を容易にしないため無意味です。それは潜在的に彼/彼女が保護されていると考えるようにウェブマスターをだましてセキュリティホールを開けます。代替のファイル拡張子(たとえばjpgではなくjpeg)、大文字、またはファイル拡張子がまったくない(linuxシステムでは一般的な)ユーザーにとっては、お尻が痛くなることがあります。

184
The Surrican

changeイベントを使用して、ユーザーが選択した内容を監視し、その時点でファイルが受け入れられないことを通知することができます。実際に表示されるファイルのリストは制限されませんが、サポートが不十分なaccept属性以外に、クライアント側でできる最も近いものです。

var file = document.getElementById('someId');

file.onchange = function(e) {
  var ext = this.value.match(/\.([^\.]+)$/)[1];
  switch (ext) {
    case 'jpg':
    case 'bmp':
    case 'png':
    case 'tif':
      alert('Allowed');
      break;
    default:
      alert('Not allowed');
      this.value = '';
  }
};
<input type="file" id="someId" />

JSFiddle

84

はい、その通りです。 HTMLでは不可能です。ユーザーは自分が望むファイルを選択することができます。

拡張子に基づいてファイルを送信しないようにするために、 JavaScript のコードを書くことができます。しかし、これは決して悪意のあるユーザーが彼/彼女が本当に望んでいるどんなファイルも提出するのを妨げるというわけではないことに注意してください。

何かのようなもの:

function beforeSubmit()
{
    var fname = document.getElementById("ifile").value;
    // check if fname has the desired extension
    if (fname hasDesiredExtension) {
        return true;
    } else {
        return false;
    }
}

HTMLコード

<form method="post" onsubmit="return beforeSubmit();">
    <input type="file" id="ifile" name="ifile"/>
</form>
45

技術的には、accept要素に input属性html5 の代替)を指定できますが、正しくサポートされていません。

18
zzzzBov

inputタグをaccept属性と共に使用する

<input type="file" name="my-image" id="image" accept="image/gif, image/jpeg, image/png" />

クリック 最新のブラウザ互換性表はこちら

ライブデモ ここ

画像ファイルのみを選択するには、これを使用することができますaccept="image/*"

<input type="file" name="my-image" id="image" accept="image/*" />

ライブデモ ここ

Only gif, jpg and png will be shown, screen grab from Chrome version 44 gif、jpg、およびpngのみが表示され、Chromeバージョン44からスクリーングラブ

9
kiranvj

私はこれが少し遅れているのを知っています。

function Validatebodypanelbumper(theForm)
{
   var regexp;
   var extension =     theForm.FileUpload.value.substr(theForm.FileUpload1.value.lastIndexOf('.'));
   if ((extension.toLowerCase() != ".gif") &&
       (extension.toLowerCase() != ".jpg") &&
       (extension != ""))
   {
      alert("The \"FileUpload\" field contains an unapproved filename.");
      theForm.FileUpload1.focus();
      return false;
   }
   return true;
}
7
bpross

実際にはjavascriptでそれを行うことができますが、jsがクライアント側であることを覚えておいてください。したがって、あなたがしなければならない特定の種類のファイルを避けたい場合サーバー側で行います。

この基本的なツールを見てください サーバサイドの検証を始めたいのならば/ /チュートリアル全体については このページ をご覧ください。

がんばろう!

5
Trufa

以前の回答で述べたように、ユーザーが特定のファイル形式だけを選択するように制限することはできません。しかし、HTMLのfile属性にacceptタグを使用するのは本当に便利です。

検証については、サーバー側で行う必要があります。クライアント側でもjsでそれを行うことができますが、それは絶対確実な解決策ではありません。サーバー側で検証する必要があります。

これらの要件のために私は本当にstruts2 Java Webアプリケーション開発フレームワークを好みます。組み込みのファイルアップロード機能を使用して、struts2ベースのWebアプリにファイルをアップロードするのは簡単です。私達が私達のアプリケーションで受け入れたいファイルフォーマットについて言及するだけで、残りはフレームワーク自体のコアによって処理されます。あなたはstrutsの公式サイトでそれをチェックアウトすることができます。

2
svg