* [CODE(HTMLe)[script]] 要素型 (HTML, XHTML 1)
@@
[CODE(HTMLe)@en[[[script]]]][[要素型]]の現実の処理は[[HTML 5]]で規定されると思われます。
ここでの説明は[[HTML 4]]に基づいており、実装を必ずしも正確に反映していません。
[1] [ABBR[[[HTML]]] [Hypertext Markup Language]] の
[DFN[[CODE(HTMLe)[script]] 要素]]は、
文書中に[[スクリプト]]を配置します。
[29] 仕様書:
- [[HTML 4]]
-- [CITE[18 Scripts in HTML documents]]
-- [CITE[Element content]]
- [[ECMA-290]]
- [[XHTML 1.0]]
-- [CSECTION[4.8. Script and Style elements]]
(参考)
[9]
:[[開始タグ]]:必須
:[[終了タグ]]:必須
:出現できる文脈:[CODE(HTMLe)[[[head]]]] の子として、または [CODE(HTMLe)[[[body]]]]
子孫の大抵の場所で
:[[内容模型]]:[CODE(SGML)[[[CDATA]]]] ([[HTML 4]]), [CODE(XML)[[[PCDATA]]]] ([[XHTML 1]])
:[[属性]]:
,属性名 ,属性値 ,既定値 ,説明 ,出典
,[CODE(HTMLa)[[[archive]]]] , , ,[NC4]
,[CODE(HTMLa)[[[charset]]]] ,[CODE(SGML)[%[[Charset]]]] , ,charset ヒント ,[HTML 4]
,[CODE(HTMLa)[[[classname]]]] ,[[逆ドメイン名]] , ,級名 ,[ECMA-290]
,[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]] , ,事象対象
[[#comment]]
** 出現できる文脈
[14] [CODE(HTMLe)[script]] 要素は、 [CODE(HTMLe)[[[head]]]] 要素や
[CODE(HTMLe)[[[body]]]] 要素の中の大抵の場所に出現できます
[SRC[HTML 4 18.2.1]]。
[15]
しかし、[[不思議マーク付け]]の世界や多くの [[WWWブラウザ]]の実装では、
[CODE(HTMLe)[[[html]]]] タグの前後や [CODE(HTMLe)[head]] 要素と
[CODE(HTMLe)[body]] 要素の間を含めて、あらゆる場所に出現できるようです。
[CITE[ダイナミックHTML入門]]
(Bruce Campbell + Rick Darnell 著, 安藤慶一訳) という入門書では、
[Q[スクリプトの場所に関しては標準規格は必要ないようです]]
などと電波を飛ばしているそうです。
[SRC[[CITE[いくつかの書籍のあらさがし]] ]]
[[#comment]]
** 内容
[4] [CODE(HTMLa)[[[src]]]] 属性が指定されている場合、
スクリプトはその外部資源で定義されます。
[ABBR[[[UA]]] [利用者エージェント]]
は[[内容]]を無視し、指定された
[ABBR[URI] [統一資源識別子]] のスクリプトを取り寄せなければなりません。
[CODE(HTMLa)[src]] 属性が指定されていない場合、
[VAR[UA][利用者エージェント]]
は内容をスクリプトとして解釈しなければなりません。
[SRC[HTML 4 18.2.1]]
[30] [ABBR[[[XHTML]]] [拡張可能ハイパーテキスト・マーク付け言語]]
より前の [ABBR[HTML] [ハイパーテキスト・マーク付け言語]] では、
[CODE(HTMLe)[script]]
要素の内容は [CODE(HTMLe)[[[style]]]] 要素の内容同様[[文字データ]]
([CODE(SGML)[[[CDATA]]]]) 宣言内容とされていました。
つまり、 [CODE(HTMLe)[script]] 要素内ではほとんどの[[マーク]]は認知されず、
[ABBR[[CODE(SGML)[[[etago]]]]] [終了タグ開き]] ([CODE(HTML)[]]) の
直後に[[名前開始文字]] [WEAK[([[ラテン文字]]など)]] または
[ABBR[[CODE(SGML)[[[tagc]]]]] [タグ閉じ]] ([CODE(HTML)[>]])
が来たらそこで [CODE(HTMLe)[script]] 要素が終わることになっていました。
ですから、スクリプト言語の[[演算子]]などとして
[ABBR[HTML] [ハイパーテキスト・マーク付け言語]]
の[[マーク文字]]が登場することがよくありますが、
そのような場合にもほとんど[[文字参照]]化する必要がありませんでした。
[36]
[ABBR[[CODE(SGML)[[[ETAGO]]]]] [終了タグ閉じ]] がかけないのは
[CODE(JS)[[CODE(DOMa)[[[document]]]].[CODE(DOMm)[[[write]]]]]]
のデータを作る時などにしばしば問題となり、その最盛期には、
これが原因でうまく動かないことに悩む人もよく見受けられました。
回避するためには、そのスクリプト言語の文字列連結を使ったり
([SAMP(JS)['<' + '/a>']])、 escape (quote) 機能を使ったり
([SAMP(JS)['<\/a>']])、文字生成関数を使ったり
([SAMP(VB)["<" & [[Chr]] (47) & "a>"]])
する方法がよく紹介されました。
[33] しかし、 [ABBR[[[XML]]] [拡張可能マーク付け言語]] では
[ABBR[[CODE(SGML)[CDATA]]] [文字データ]] 宣言内容は使えないので、
[ABBR[[[XHTML 1]]] [拡張可能ハイパーテキスト・マーク付け言語 1]] では
[ABBR[[CODE(XML)[[[PCDATA]]]]] [解析可能文字データ]]
と宣言されています。
ですから、 [ABBR[[CODE(SGML)[STAGO]]] [開始タグ開き]]
([CODE(XML)[<]]) は必ず [[escape]]
して [CODE(XML)[<]] としなければならないなどの制限があります。
これを回避するために [[[CODE(XML)[CDATA]]区間]]を使う方法がよく紹介されますが、
そうすると多くの既存の [ABBR[WWW] [World Wide Web]]
ブラウザとの互換性が失われてしまいます。
ですから、 [ABBR[XHTML] [拡張可能ハイパーテキスト・マーク付け言語]] で
[CODE(HTMLe)[script]] 要素を使う時は [CODE(HTMLa)[src]]
属性を使った外部スクリプトとするのが良いと言われています。
[41]
[CODE(HTMLa)[src]] で指定された資源が取得できない時に内容を使うとする説があります。
[CITE[SCRIPT - Client-side Script(jp)]]
しかし、 [ABBR[HTML] [ハイパーテキスト・マーク付け言語]] 4
の規定と矛盾します。
[WEAK[(この文書はほんとうに [ABBR[HTML] [ハイパーテキスト・マーク付け言語]] 4 に基づいているのでしょうか?)]]
[47]
[CITE[Working with the WebKit Nightly Builds]]
([[名無しさん]] [WEAK[2006-11-05 02:47:22 +00:00]])
[48]
[CITE[Surfin’ Safari - Blog Archive » Understanding HTML, XML and XHTML]]
([[名無しさん]])
[[#comment]]
*** 擬似注釈宣言の使用
[18] [CODE(HTMLe)[script]] 要素に対応していない古い WWW ブラウザは、
[CODE(HTMLe)[script]] 要素内の[[文字データ]]も構わず解釈してしまいます。
そこで、 [CODE(HTMLe)[script]] 要素の内容としてスクリプトを記述するときには、
HTML の[[注釈宣言]]のように最初に [CODE(HTML)[]] をつけることが慣習となっています。
HTML 4 によれば、これは HTML の機能ではなく、[[スクリプト機関]]の機能とされています。
この機能に対応している言語には [[JavaScript]], [[VBScript]], [[Tcl]]
があるようです。 [SRC[HTML 4 18.3.2]] より正確には、この3つの言語は
[CODE(HTMLe)[script]] 要素の内容の一番最初の非[[空白]]文字列が
[CODE[]] は、3つの言語のいずれも、それだけで書くことはできず、
それぞれの言語の注釈の内容として (JavaScript の場合は [SAMP(JS)[// -->]]
のようにして) 書くことが必要らしいです。
[Q[らしい]]というのは、正確にこれを規定した仕様がないからです。
HTML 4 は[Q[スクリプト機関]]によるものだと言っていますから、
スクリプト言語の言語仕様かなにかに規定があってもよさそうなものですが、
そのようなものは見たことがありません。また、 HTML
に直接埋め込まれていない [[ECMAScript]] のスクリプトのソース・コードに
[CODE[
]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[ 内の要素はすべてコメントで囲んだ方が安全です。]]
[[#comment]]
** UA による利用
[28] [CODE(HTMLe)[script]] 要素によるスクリプトは、
文書の読込み時に実行されます [SRC[HTML 4 18.1]]。
[CODE(HTMLa)[src]] 属性による外部スクリプトは優先的に実行されるという説を唱える人がいますが、
根拠は不明です。特定の UA ではそうなのかもしれませんが、
少なくても HTML 4 は何も規定していません。
但し、 [CODE(HTMLa)[[[defer]]]] 属性や [CODE(HTMLa)[[[event]]]]
属性は実行時機に影響するのかもしれません。
[[#comment]]
** 安全性
[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年)。
[[#comment]]
** 実装
[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: