JavaScript の MIME は。

タイトルはついさっき遅ればせながら『君の名は。』を観たばかりという個人的理由からで、それ以上のものではありません。映画の感想ですが、三葉が東京に行くシーンで高山線のキハ40系気動車キター、と思ったら内装はJR東日本のキハ100系っぽい矛盾が気になって気になってその後の展開が頭に入りませんでした。感想終わり。

さて、今や JavaScript を使用しないサイトなど皆無な時代、みなさんは JavaScript の MIME を何に設定していますか。

RFC 4329

JavaScript の MIME は2006年に公開されたRFC 4329(tools.ietf.org)にて下記の4つが定義されています。

  • text/javascript
  • application/javascript
  • text/ecmascript
  • application/ecmascript

しかしながら、

Use of the "text" top-level type for this kind of content is known to be problematic.

RFC 4329 の第3章(tools.ietf.org)

という理由により、 text/javascripttext/ecmascript は obsolete の扱いとなっています。

また、 application/ecmascript のみはこんな記述があります。

For the application/ecmascript media type, implementations MUST NOT process content labeled with a "version" parameter as if no such parameter had been specified; this is typically achieved by treating the content as unsupported.

RFC 4329 の第3章(tools.ietf.org)

"version" パラメーターが付いた場合にそれを無視してはいけない(MUST NOT)。通常は(パラメーターなしの時と同じように処理するのではなく)未サポート扱いにすることで実現される、ということですね。

HTML LS および HTML5

HTML の <script> 要素の記述はどうでしょうか。

HTML4 の時代は type 属性が必須でしたが、 HTML Living Standard および HTML5 では省略可能で、

Authors should omit the attribute, instead of redundantly giving a JavaScript MIME type.

4.12.1 The script element の type 属性の説明(html.spec.whatwg.org)

と書かれているため、 <script type="text/javascript" src="..."><script type="application/javascript" src="..."> ではなく、単に <script src="..."> と書くのが良いと理解できます。

なお、省略時の値は text/javascript と規定されています。(4.12.1.1 Processing model(html.spec.whatwg.org)より)

さて、困ったことになりました。 RFC 4329 では text/* は obsolete と言われてしまっているのに、 HTML 側の仕様では「省略せよ、なおその時は text/javascript と解釈する」と言うのです。どうしろと……。

ブラウザの対応

今では気にする必要のないことですが、 RFC 4329 が公開された当時はまだ幅を効かせていた Internet Explorer という残念なブラウザはバージョン8まで application/javascriptapplication/ecmascript を認識しないという残念っぷりをいかんなく発揮しており、現実問題として obsolete な text/javascript を採用せざるを得ない事情がありました。

なので、多くのサイトでは MIME を text/javascript に設定し、HTMLは <script src="..."> と記述しつつ、「ホントは obsolete なのに……」と悶々とした日々を過ごしていたエンジニアも多いのではないでしょうか。

ちなみにHTMLは <script src="..."> としたうえで MIME だけ application/javascript にしてもメジャーなブラウザでは問題が起こりません。弊サイトは何年も前からそのように設定しています(2017年8月現在)。

RFC 4329 のアップデート

そんな状況下、 ES Module の兼ね合いで RFC 4329 がアップデートされそうです。

このドラフトでは拡張子 .mjs が追加されている他、 text/javascript が OBSOLETE から COMMON に変更されています。その理由としてはまさにHTML仕様でのデフォルト値が text/javascript であることが挙げられています。

Finally, the [HTML] specification is using text/javascript as the default media type of ECMAScript when preparing script tags; therefore, text/javascript has been moved intended usage from OBSOLETE to COMMON.

EMCAScript Media Types Updates の第4章(tools.ietf.org)

結局のところ、 RFC 4329 で「JavaScript を text/* にすることは問題がある」と書かれつつも、現実的に問題は発生しておらず、今後も text/javascript を使い続けても構わない、ということでしょうね。

もっとも、 IE 8 がとうの昔に消え去った今、 application/javascript の方を採用してもいいとは思いますが。