<input accept> の対応状況 2017

ファイルアップロード時に用いられる input 要素の File Upload state (type=file) では、accept 属性(html.spec.whatwg.org)を設定することで、特定のファイルを選択しやすいようにすることができます。

この accept 属性については唯一 Opera のみが対応していた時代から個人的に注目していたのですが、ようやく仕様書の定義にブラウザの実装が追いついてきたので、改めてまとめてみます。参考までに、これまで当ブログや当時勤務していた会社のブログに書いた記事のリンクを貼っておきますが、いずれも古い記事なので歴史的な経緯を知りたいといった目的でもなければ参照する必要はありません。

  1. accept 属性とは
  2. accept 属性値の種類
  3. 対応ブラウザ
  4. MIMEタイプと拡張子は両方の指定が推奨

accept 属性とは

§

たとえば画像と動画を投稿するフォームでは

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

と指定することで、ファイル選択ダイアログにて画像・動画以外のファイルを非表示にするなど、目的のファイルを選択しやすいようにすることができます。

昨今では Twitter や Mastodon、Facebook、Flickr など著名なサービスでも広く使われています。

画像1Facebook の「写真・動画」投稿ボタンのソースコード

なお、あくまでデフォルトで指定外のファイルを選択できないようにするというだけであり、ユーザーがファイル選択ダイアログで「すべてのファイル」に自主的に変更してしまえば指定外のファイルを送信することも可能です。指定外のファイルがアップロードされると困る場合は、accept 属性の有無に関わらずサーバーサイドでの判定処理が必要です。

accept 属性値の種類

§

accept 属性は HTML4 の時代から定義されていますが、現在では以下の3タイプを指定することができます。

  • 文字列 "audio/*", "video/*", "image/*"
  • パラメーターのないMIMEタイプ("image/png", "text/plain" など)
  • "." (U+002E) で始まるファイル拡張子

これらをカンマ区切りで複数指定できます。先に挙げた Facebook の場合、画像は image/* のみですが、動画はさまざまな形式に対応するためか多くの値が指定されています。

accept="video/*, video/x-m4v, video/webm, video/x-ms-wmv, video/x-msvideo, video/3gpp, video/flv, video/x-flv, video/mp4, video/quicktime, video/mpeg, video/ogv, .ts, .mkv, image/*"

対応ブラウザ

§

「Can I use...」のaccept attribute for file input(caniuse.com)を参照するのが早いですが、一応書いておきます。

"audio/*", "video/*", "image/*"、およびMIMEタイプの指定に関しては、PC向けの主要ブラウザは Edge を除き対応済みですが、 Android 用の Firefox は未対応です。

ファイル拡張子の指定は2012年にHTML仕様書に取り込まれた比較的新しい書き方なため、 Safari の対応が遅れていましたが、2017年8月23日付でリリースされたRelease Notes for Safari Technology Preview 38(webkit.org)で対応されたとのことで、次の正式版で取り入れられるものと思われます。

MIMEタイプと拡張子は両方の指定が推奨

§

HTML仕様書にはこんな記述があります。

Authors are encouraged to specify both any MIME types and any corresponding extensions when looking for data in a specific format.

4.10.5.1.17 File Upload state (type=file)(html.spec.whatwg.org)

著者は、特定の形式でデータを検索する際、任意のMIMEタイプと対応する拡張子の両方を指定することが推奨される。

4.10.5.1.17 File Upload状態(type=file)(momdo.github.io)

この理由については、あくまで個人的な推測ですが2つの意味合いがあると思っています。

ひとつは後方互換性を保つ目的。拡張子指定は前述のとおり後から仕様に追加されたものなため、現状 Safari が未対応であり、また一昔前は Firefox もバージョン36までは未対応だった経緯から、拡張子のみの指定だとそれらのブラウザに対応することができない点です。両方の指定をしておけば、拡張子指定に未対応のブラウザでもMIMEタイプの認識は行われるので(拡張子の記述のみ無視される)、後方互換性は確保されます。

もう一つは、拡張子も MIME もファイルの種類を示すのに確実なものではないという性質上の理由です。これは仕様書内にも記載がありますが、例えば ".dat" という拡張子はフォーマットがさまざまであり、一方の MIME も IANA に正式登録(www.iana.org)されていないものが多数あり、またいずれもユーザーのマシン設定やサーバー設定により何とでも改変や独自設定が可能です。

そのため、「画像」「動画」など広い範囲のファイルを受け入れる場合は MIME と拡張子の両方の指定を検討した方が良いですし、一方で「PNG画像のみ」といったような特定のフォーマットに絞る場合は片方だけの指定でも構わないと思います。