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


667

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


1
PHPで簡単に可能ですが、それを使用できるかどうかわからないので、コードは投稿しません。
Latox

2
私がすることができますが、私はJavaScriptで作業ソリューションを持っている-それは、ファイルをアップロードするの迷惑除去し、その後取得し、「間違ったファイルを!」エラー。
Bojangles 2010

:また、より最近の質問参照stackoverflow.com/questions/181214/...
クリストフRoussy

注意すべき点の1つは、検証には適していませんが、ユーザーがファイルを閲覧している間(少なくとも一部のブラウザーでは)、acceptは表示されるファイルを許可されたファイルに制限します。したがって、これは検証機能よりもUIのエルゴノミー機能です。
Christophe Roussy

回答:


1119

厳密に言えば、答えはノーです。開発者、ユーザーが任意のタイプまたは拡張子のファイルをアップロードすることを防ぐことはできません

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

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

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

したがって、IE 10 +、Edge、Chrome、Operaとともに42より古いFirefoxをサポートするには、MIMEタイプのコンマ区切りのリストを使用する方がよいと思います。

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

[ Edge(EdgeHTML)の動作:ファイルタイプフィルターのドロップダウンには、ここに記載されているファイルタイプが表示されますが、ドロップダウンのデフォルトではありません。デフォルトのフィルターは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 --> 

W3C 、MIMEタイプと対応する拡張子の両方をaccept属性で指定することを作成者に推奨しています。したがって、最善のアプローチは次のとおりです。

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

JSFiddle of the same:here

参照: MIMEタイプのリスト

重要:このaccept属性を使用すると、目的のタイプのファイルをフィルタリングする方法のみが提供されます。ブラウザは、ユーザーが任意のタイプのファイルを選択できるようにします。追加の(クライアント側)チェックを実行する必要があります(JavaScriptを使用して、1つの方法はこれです)。ファイル拡張子とそのバイナリ署名(ASPの両方)を使用するMIMEタイプの組み合わせを使用して、サーバー上でファイルタイプを確認する必要があります.NETPHPRubyJava)。ファイルタイプとそのマジックナンバーについては、これらの を参照することもできます。、より堅牢なサーバー側の検証を実行します。ファイルのアップロードとセキュリティに関する3つの優れた記事

次に示します。

編集: おそらくバイナリ署名を使用したファイルタイプの検証は、HTML5ファイルAPIを使用して(拡張機能を見るだけでなく)JavaScriptを使用してクライアント側でも実行できますが、悪意のあるユーザーがファイルをサーバーで検証する必要がありますカスタムHTTPリクエストを行うことでファイルをアップロードできます。


2
@Sandesire HTMLのファイルサイズを制限できるとは思いません。あなたが提案したように、それはJavaScriptを使用して可能です。
Sachin Joseph

1
私の個人的な経験から、これは良い答えのように見えます。mimeタイプだけでは、すべてのブラウザーで機能するわけではありません。
Christophe Roussy

1
ちなみに、acceptそれでもEdgeでは動作しません:stackoverflow.com/questions/31875617/…。その他の詳細はこちら:wpdev.uservoice.com/forums/257854-microsoft-edge-developer/...
SharpC

1
たとえば、ファイルも除外する選択肢があったらいいのにと思いますexclude="exe"。_(ツ)_ /¯
Sagiv BG

1
(私のテストによると)Edgeの動作をさらに明確にするために、指定した内容に基づいて異なるフィルターを追加しますが、a)バンドルされていないため、各拡張機能を個別のオプションとしてリストし、b)常にいくつかのオプションを追加します.htmlやc)などの拡張子をビルドします。すでに述べたように、常に事前選択(*)します。これは、多くの場合それを大きな混乱にさせ、役に立たないものにします。私はuservoiceリンクに投票しました。遅かれ早かれ彼らが聞いてくれることを望みます。
Arie

198

inputタグにはaccept属性があります。ただし、信頼性はありません。ブラウザーはほとんどの場合、それを「提案」として扱います。つまり、ユーザーは、ファイルマネージャーにもよりますが、目的のタイプのみを表示する事前選択を持っています。「すべてのファイル」を選択して、必要なファイルをアップロードできます。

例えば:

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

HTML5仕様の詳細を読む

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

答えはあるので:あなたが制限することはできませんが、あなたはできる事前選択を設定していますが、できません、それに依存しています。

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


3
追加情報については、stackoverflow.com
questions / 181214 /…を

1
ユーザーが最終的に任意のタイプのファイルを選択できないようにすることは不可能ですが、最近では、HTML5 File APIを利用して、選択したファイルを実際にサーバーにアップロードする前に、検出を含めてアップロードすることができます。そのタイプ、サイズなど。試してみる。非常に使いやすく、しかも非常に強力で便利です。
TheCuBeMan 2017年

96

あなたは使用することができます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


11
@joe、それは例です...それはあなたが許可したいどんな拡張にも拡張できます。
ガブリエレペトリオーリ2010

はい、できます。しかし、あなたはそうではありません!そして、maby誰かがすでにそれをコピーしました!正しいMIMEタイプで拡張子のないファイルはどうなりますか?
Surrican 2010

49
@Joe ..まあ..私は方向性と健全な論理を提供しようとします。すべてのケースに完全に実装されたソリューションではありません。私は視聴者がWebからコードをコピー/貼り付けるときに常識を使用することを信頼しています;)
Gabriele Petrioli

7
「Some.File.jpg」はどうですか?おそらく、その正規表現の行を読み取る必要があります。var ext = this.value.match(/ \。([^。] +)$ /)[1];
Jon Kloske 2013年

このアプローチの問題は、その拡張子で終わっていなくても、技術的にはまだjpegである可能性があることです。拡張機能!== MIMEタイプ
Matt Fletcher

46

はい、そうです。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>

3
そのための完全に有効なhtml属性があるので、それは可能です。これはブラウザによって尊重されるだけではありませんが、それは標準化の問題です。保護されていないマークアップでクライアント側で処理されるものと同様、Javaスクリプトを制限することはできません。解決策はありません。
のSurrican

2
非常に良い点です。念のため、2つ目のPHPチェッカーを追加します。注意しすぎないでください!
Bojangles

2
まあ、私がPHP検証スクリプトを使用しても害はないので、両方を使用します。
Bojangles 2010

17
@ジョー:私の答えが悪いと言うのをやめて!:-)とにかく、それは完璧な解決策ではありません。冒頭で述べたように、OPが望むことを「実行することは不可能」です。しかし、あなたが持つことができるいくつかのあなたは彼だけを許可すれば、ユーザーのヘルプの度合いを/彼女は、特定の拡張子を持つファイルを選択します。REALファイルタイプの検証はサーバー側で行う必要があります
Pablo Santa Cruz

11
@JoeHopfgartner:おい、パブロにとってここは非常に厳しい。クライアントサイドの検証は多くの場所で行われ、絶対確実ではありませんが([b]常に[/ b]サーバーサイドの検証が含まれている必要があります)、ユーザーをかなりの時間節約できます(愚かな拡張チェックなどのポストバックはありません)。Pabloによって提供されたスクリプトは完全ではありませんが、この問題に取り組む方法の例を示すことのみを目的としています... Microsoftの技術担当者にメールを送り、クライアント側の検証をASP.NETバリデーターから削除するよう依頼する必要があるかもしれませんそれはすべてあなたにとって平凡なゴミです...
ネイサン

18

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


W3Schoolsブラウザーのサポートが失敗しました!本当に残念です。これはセキュリティ上の問題でもあります。人々は過去のクライアント側のコードをハックして、好きなものをアップロードできます。
Bojangles 2010

5
確かに、これをセキュリティのために使用しないことが最善ですが、それをサポートするブラウザでの使いやすさは間違いなく役立ちます。ユーザーには、サイトで許可されているファイルのみが表示され(同じフォルダーにある可能性のある他のすべてのジャンクではありません)、エラーが発生するためにアップロードプロセス全体を実行する必要はありません。すぐにわかります。コーダーこれ使用する必要があります。
Simon East、

10

属性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/*" />

ここでライブデモ

gif、jpg、pngのみが表示され、Chromeバージョン44から画面を取得 gif、jpg、pngのみが表示され、Chromeバージョン44から画面を取得


ありがとう!Win10上のChromeでは、を使用accept="image/*"すると、ファイルピッカーで「カスタムファイル」ではなく「イメージファイル」と表示されます。これはエンドユーザーにとって便利です。
テディ

しかし、ユーザーはそれを変更して他の拡張ファイルをアップロードできます
Prashant Prajapati

@PrashantPrajapatiはい、ブラウザの作成方法です。サーバーで対応する検証を行う必要があります。ブラウザ機能は、ユーザーエクスペリエンスを向上させるためのものです。
kiranvj

9

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

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;
}

5

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

サーバー側の検証を開始したい場合は、この基本的な説明をご覧ください。チュートリアル全体については、このページにアクセスしてください

幸運を!


4

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

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

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


3

私は以下を提案するかもしれません:

  • ユーザーにデフォルトで画像ファイルのいずれかを選択させる必要がある場合は、accept = "image / *"を使用します。

    <input type="file" accept="image/*" />

  • 特定の画像タイプに制限する場合は、accept = "image / bmp、image / jpeg、image / png"を使用します

    <input type="file" accept="image/bmp, image/jpeg, image/png" />

  • 特定のタイプに制限したい場合は、accept = "。bmp、.doc、.pdf"を使用します

    <input type="file" accept=".bmp, .doc, .pdf" />

  • ユーザーがファイルファイラーをすべてのファイルに変更することを制限できないため、常にスクリプトとサーバーでファイルタイプを検証してください


1
これが私が探していたものでした。accept= "。bmp"はchromeで正常に動作します。
MichaelRom
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.