[1] [[HTML]] の [DFN[[CODE(HTMLe)@en[[[script]]]]]] [[要素]]は、動的な[[スクリプト]]や、
[[スクリプト]]が使うデータを[[文書]]に埋め込むものです。
[9]
:[[開始タグ]]:必須
:[[終了タグ]]:必須
:出現できる文脈:[CODE(HTMLe)[[[head]]]] の子として、または [CODE(HTMLe)[[[body]]]]
子孫の大抵の場所で
:[[属性]]:
,属性名 ,属性値 ,既定値 ,説明 ,出典
,[[大域属性]]
,[CODE(HTMLa)[[[archive]]]] , , ,[NC4]
,[CODE(HTMLa)@en[[[async]]]]
,[CODE(HTMLa)[[[charset]]]] ,[CODE(SGML)[%[[Charset]]]] , ,charset ヒント ,[HTML 4]
,[CODE(HTMLa)[[[classname]]]] ,[[逆ドメイン名]] , ,級名 ,[ECMA-290]
,[CODE(HTMLa)@en[[[crossorigin]]]]
,[CODE(HTMLa)[[[defer]]]] ,([[真偽値属性]]) ,(偽) ,遅延評価 ,[HTML 4]
,[CODE(HTMLa)[[[event]]]] , , ,[[事象]] ,[HTML 4] 予約
,[CODE(HTMLa)[[[for]]]] ,[CODE(SGML)[[[IDREF]]]] , ,対象 ,[HTML 4] 予約
,[CODE(HTMLa)[[[id]]]] ,[CODE(SGML)[[[ID]]]] ,(なし) ,固有識別子
,[CODE(HTMLa)[[[language]]]] , , ,スクリプト言語 ,[HTML 4] 非推奨
,[CODE(HTMLa)[[[name]]]] , , , ,非標準
,[CODE(HTMLa)[[[purpose]]]] , , ,実行目的 ,[ECMA-290]
,[CODE(HTMLa)[[[src]]]] ,[CODE(SGML)[%[[URI]]]] ,(内容) ,外部スクリプト ,[HTML 4]
,[CODE(HTMLa)[[[type]]]] ,[CODE(SGML)[%[[ContentType]]]] ,(必須) ,[[スクリプト言語]] ,[HTML 4]
,[CODE(XMLa)[[VAR[ev:]][[event]]]] ,[CODE(ABNF)[[[QName]]]] ,(なし) ,[[事象名]]
,[CODE(XMLa)[[VAR[ev:]][[observer]]]] ,[CODE(XML)[[[IDREF]]]] , ,[[事象観察器]]
,[CODE(XMLa)[[VAR[ev:]][[phase]]]] , , ,
,[CODE(XMLa)[[VAR[ev:]][[propagate]]]] , , ,[[伝播]]制御
,[CODE(XMLa)[[VAR[ev:]][[target]]]] ,[CODE(XML)[IDREF]] , ,事象対象
* 仕様書
[REFS[
- [130] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2013-12-19 00:10:55 +09:00]] 版)
]REFS]
* 意味
[131] [CODE(HTMLe)@en[[[script]]]] [[要素]]は、動的な[[スクリプト]]や、データブロックを[[文書]]に含めるために使うことができます。
[SRC[>>130]]
;; [134] どちらであるかは [CODE(HTMLa)@en[[[type]]]] [[属性]]や [CODE(HTMLa)@en[[[language]]]]
[[属性]]によって決まります。
[132] [CODE(HTMLe)@en[[[script]]]] [[要素]]は[[利用者]]に対する[[内容]]を[[表現]]していません。 [SRC[>>130]]
* 動的なスクリプト
[133] 動的な[[スクリプト]]として [CODE(HTMLe)@en[[[script]]]] [[要素]]を使う時は、
- [[スクリプト]]を[[要素]]の[[内容]]として直接埋め込むか、
- 外部の[[スクリプト]]を [CODE(HTMLa)@en[[[src]]]] [[属性]]によって参照するか
... のどちらかの方法となります [SRC[>>130]]。
[135] [CODE(MIME)@en[[[text/javascript]]]] 以外の[[スクリプト言語]]の時は、
[CODE(HTMLa)@en[[[type]]]] [[属性]]は[['''必須''']]です [SRC[>>130]]。
[136] [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[内容]]は、
[[スクリプト言語]]の仕様により定められた要件に従わなければ[['''なりません''']] [SRC[>>130]]。
* データブロック
[137] データブロックとして [CODE(HTMLe)@en[[[script]]]] [[要素]]を使う時は、
[[要素]]の[[内容]]として直接埋め込まなければ[['''なりません''']] [SRC[>>130]]。
[138] [CODE(HTMLa)@en[[[type]]]] [[属性]]は[['''必須''']]であり、
[CODE(HTMLa)@en[[[src]]]] [[属性]]は使っては[['''なりません''']] [SRC[>>130]]。
[139] [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[内容]]は、
[CODE(HTMLa)@en[[[type]]]] [[属性]]で指定された書式の要件に従わなければ[['''なりません''']] [SRC[>>130]]。
* 構文
** タグ
[68] [CITE[Bug 6357 –
]PRE]
のように自然言語の注釈を入れておくことがよく行われていました
(初期の使用例にそう載っていたからみんなで真似したのでしょう)。
(この例のように開き (のようなもの) の後に書くこともできましたが、
閉じの前に書くのが普通だったと記憶しております。)
後にこのような冗長なことはせず、
[PRE(HTML)[
]PRE]
のように簡単に書くようになりました。
[35] また、[Q[裏技]]的なものとして、
[PRE(HTML)[
]PRE]
のような書き方が紹介されることもありました。
(この例のようになぜかスクリプトの途中に書いているものもあれば、
注釈宣言 (のようなもの) の前後に書いているものもありました。
どこに入れるにせよ、書く内容は一行にするか、
うまくして行頭にスクリプト言語の注釈導入子が来るように調整することが重要です。
また、 [CODE(SGML)[[[etago]]]] が使えないことにも注意が必要です。)
[38] スクリプト言語の演算子として [CODE[>]] を使うことが良くありますが、
古いブラウザの中には注釈宣言を [CODE[>]] で終えてしまうものがあることが知られています。
[SAMP(JS)[[VAR[x]] > [VAR[y]]]] のような式は [SAMP(JS)[[VAR[y]] < [VAR[x]]]]
と書くことで回避できます。 [SRC[HTML 4 18.3.2 Note]]
もっとも、そのようなブラウザは HTML 4 の時点でも骨董品ですし、
HTML 4 も特にそうするべきだなどとは言っていません。
参考文献:
- [16] [CITE[ 内の要素はすべてコメントで囲んだ方が安全です。]]
誤って「[CODE(JS)@en[//->]]」のようなもので終わることもあるみたいです。
[[#comment]]
** 処理モデル
[28] [CODE(HTMLe)[script]] 要素によるスクリプトは、
文書の読込み時に実行されます [SRC[HTML 4 18.1]]。
[CODE(HTMLa)[src]] 属性による外部スクリプトは優先的に実行されるという説を唱える人がいますが、
根拠は不明です。特定の UA ではそうなのかもしれませんが、
少なくても HTML 4 は何も規定していません。
但し、 [CODE(HTMLa)[[[defer]]]] 属性や [CODE(HTMLa)[[[event]]]]
属性は実行時機に影響するのかもしれません。
*** 構文解析との関係
[63]
[CODE(HTMLa)@en[[[defer]]]]、[CODE(HTMLa)@en[[[async]]]] なしの場合で、
[CODE(HTMLa)@en[[[src]]]] ありの場合に、外部[[スクリプト]]が実行されるまで[[構文解析]]は停止するか?
[CITE[Index of /~wakaba/-temp/test/html/script/src]] ([TIME[2008-12-16 11:37:00 +09:00]] 版)
[64] [[HTML]] として記述された [CODE(HTMLe)@en[[[script]]]] [[要素]]の場合 (nodefer-1)、
どのブラウザも[[構文解析]]が停止します。
[65] [[DOM]] によって作成された [CODE(HTMLe)@en[[[script]]]] [[要素]]の場合 (nodefer-script-1)、
[[Opera]] 以外は[[構文解析]]を続行し、外部[[スクリプト]]は準備が出来次第実行します
([[HTML5]] に従った動作)。 [[Opera]] 9.61 は >>64 同様、[[構文解析]]を停止します。
** 安全性
[43]
'''Web メイルにおける HTML メイル''':
[[HTML]] を[[利用者界面]]として利用した [[MUA]]
(いわゆる [[Webメイル]]) で [[HTML]]
[[文書]]が含まれる[[メイル]]・[[メッセージ]]を表示する時には特に注意が必要です。
[CODE(HTMLe)@en[[[script]]]] [[要素]]など[[スクリプト]]が実行され得るものをそのまま
[[HTML]] に含めると、 [[Webブラウザ]]側でその [[HTML]] [[文書]]全体
[WEAK[([[HTMLメイル]]自体とその周りの[[利用者界面]]を含む全体)]]
の権限で[[スクリプト]]が実行されることになります。
[[Webブラウザ]]外に被害が及ぶかという点では通常の鯖側の[[スクリプト]]の安全上の脅威と変わりませんが、
[[利用者界面]]の部分を介して[[利用者]]の意図せぬ (削除などの)
操作を行ったり、受信したメッセージや個人情報が流出したりする危険性があります。
[[#comment]]
** 歴史
[2] [CODE(HTMLe)[script]] 要素は、 [[NN2]] が [[LiveScript]]
と共に実装したのがはじめであると考えられています。
[20] [CODE(HTMLe)[script]] 要素がはじめて公式な仕様書に入ったのは
1997年1月の [[HTML 3.2]] でした。しかし、
このときの最終的な勧告では詳細が決まらず、
将来の版のために予約すると述べるに留まっていました。
>
[SRC[HTML 3.2 DTD]]
[12] その後1997年12月の [[HTML 4]] で、 [CODE(HTMLe)[script]]
要素型はようやく正式な仕様の一部となりました。
当時 [[WinIE]] や [[NN]] が実装していた [CODE(HTMLe)[script]]
の基本的な機能が仕様に入りましたが、 WinIE だけが実装していた
[CODE(HTMLa)[event]] 属性と [CODE(HTMLa)[for]] 属性は、
将来のために予約とされました。
[24] 1998年に勧告された [[DOM 1]] やその後の [[DOM 2]] では、
[CODE(HTMLe)[script]] 要素型に対応する [CODE(DOMi)[[[HTMLScriptElement]]]]
界面が定義されています。ここでは、標準の属性の他、
[CODE(HTMLa)[for]] 属性と [CODE(HTMLa)[event]] 属性も[Q[将来の使用のために予約]]
として定義だけされています。
[25] >>24 そんな将来くるのかな〜。来たら嫌だな〜
[26] >>24-25 将来の使用は M$ の仕様の間違いじゃないのかな。
[32]
>>24-26
その後 [[XHTML 1]] が標準化されましたが、予約2属性はやはり正式な仕様には昇格せず、
このまま忘れ去られようとしています。しかし、両属性の機能は拡張して汎用化されて
[[XML事象]]仕様の一部として標準化されました (2002年)。
[REFS[
- [29] [[HTML 4]]
-- [CITE[18 Scripts in HTML documents]]
-- [CITE[Element content]]
- [[ECMA-290]]
- [[XHTML 1.0]]
-- [CSECTION[4.8. Script and Style elements]]
(参考)
]REFS]
*** XHTML2
[73] [[XHTML2]] 第6次案までは [CODE(HTMLe)@en[[[script]]]] [[要素]]がありましたが、
第7次案で [CODE(HTMLe)@en[[[handler]]]] に改名されました。
** 実装
[31] [CODE(file)[[[CGI.pm]]]] は、 XHTML 出力 mode だと、
[[注釈宣言]]内に [[[CODE(XML)[CDATA]]区間]]宣言という素晴らしい出力をしてくれます(w
[50]
[CITE[Bug 60724 –
]PRE]
[[VBScript]] による例
[PRE(HTML)[
]PRE]
[[Tcl]] による例
[PRE(HTML)[
]PRE]
[[#comment]]
** メモ
[44]
[CITE[XHTML Frequently Answered Questions]]
[[HTML 4]] は [[SGML]] [[応用]]なのに
[CODE(JS)@en[[[document]].[[write]]]]
が使えて、
[[XHTML 1]] は [[XML]] [[応用]]だから
[CODE(JS)@en[[[document]].[[write]]]]
が使えないというのはよくわからない。
([[名無しさん]] [WEAK[2006-08-05 06:53:16 +00:00]])
[46]
[CITE[404 Blog Not Found:javascript - scriptタグによる通信が特許侵害!?]]
([[名無しさん]] [WEAK[2006-11-04 02:20:29 +00:00]])
[49]
[CITE[Bug 178258 – document.forms has no properties on a page without (JavaScript error)]] ([CODE[2007-01-29 17:04:28 +09:00]] 版)
([[名無しさん]])
[51]
[CITE@en[HTML5 script start tag should select appropriate content model according to src]] ([[David Woolley]] 著, [CODE[2007-04-21 22:52:46 +09:00]] 版)
([[名無しさん]] [WEAK[2007-04-28 03:58:40 +00:00]])
[52]
[CITE[HTML5 IRC logs: w3c / #html-wg / 20070423]] ([CODE[2007-06-30 15:38:51 +09:00]] 版)
> [03:47] Lachy: since you were discussing Safari's handling of earlier, we might make that a Dashboard-only quirk - we foolishly did it for Firefox compatibility, and then a huge number of Dashboard widgets started relying on it, and now Firefox no longer handles it as empty in HTML
([[名無しさん]])
[53]
[CITE@en[http charset,
]PRE]
([[名無しさん]])
[55]
[CITE@en[Re: