• ベストアンサー

「<img>を<script>~</script> 内に書くことはできません」

元アルバイト先に頼まれてサイトを作り運営しているのですが、わからないことがあるので教えて下さい。 サイトはXHTML1.0 Transitional で作っており、ここに、http://fmono.sub.jp/ の「w3Analyzer」を組み込みアクセス解析をしています。サイト自体もこのアクセス解析も正常に動作しています。 ただ、このサイトをhttp://openlab.ring.gr.jp/k16/htmllint/htmllint.htmlで構文チェックすると、アクセス解析のタグにエラー「<img>を~行目の<script>~</script>内に書くことはできません。」が表示されてしまいます。 エラーが表示されるタグは下記のようなものです。 <script type="text/javascript"> document.write('<img src="http://~/w3a/writelog.php?ref='+document.referrer+'" width="1" height="1" />'); </script> > アクセスログは普通に取得できているので問題ないのですが、もし上記エラーを回避する方法があればご教授下さい。よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Chaire
  • ベストアンサー率60% (79/130)
回答No.3

XHTML には「ホンモノの XHTML」と「ニセモノの XHTML」があります。「ホンモノの XHTML」とは application/xml または application/xhtml+xml として識別されるもの、「ニセモノの XHTML」は text/html で識別されるものです。 ※実際にはどちらも本物です。ここでは「HTML 互換として処理される XHTML」を「ニセモノ」、「XML として解析される XHTML」を「ホンモノ」と、カタカナ&カッコ付きで書いています。 「ホンモノの XHTML」として見れば、質問文のソースは妥当性違反です。なぜなら、img 要素のタグがエスケープされていないため、これがスクリプトの一部ではなく文書構成要素だと判断されるからです。XHTML 1.0 のスキーマは、script 要素内に img 要素が出現することを許していません。もちろん、スクリプトとしても正しく動作しません。 従って、XML のルールに従ってエスケープする必要があります。特に「<」と「&」は必ずエスケープしなければなりません。 document.write('&lt;img .... />'); ですが面倒なことに、「ニセモノの XHTML」ではこれが動作しなくなります。「ニセモノの XHTML」は、HTML との互換性のために script 要素内の「<」「&」をうまく扱ってくれるのですが、それが仇となり、上記では「&lt;」が「<」に戻りません。 ならば、コメント区間にするのはどうでしょう。XML でもコメント内なら「<」「&」が現れても大丈夫です(ただし「--」だけは駄目です)。 <script type="text/javascript"><!-- document.write('<img .... />'); //--></script> 「ニセモノの XHTML」ならこれでも構いません。しかし、「ホンモノの XHTML」では、コメントは本当に破棄されてしまい、上記では動作すらしなくなります。 そこで、XML/HTML のルールを使わず、JavaScript のルールでエスケープすることを考えます。 document.write('\u003Cimg .... />'); これなら大丈夫でしょう。XML/HTML に限らず、言語が混在する際は必ず適切なエスケープを施す必要があります。エスケープを避けたければ外部スクリプトにして下さい。 なお、ここには別の問題があります。そもそも「ホンモノの XHTML」では、document.write を使用できません。これは HTML 互換の機能だからです(HTML5 に明記されています)。 XHTML を採用するのであれば、それが「ホンモノ」でも「ニセモノ」でも大丈夫なよう、document.write に頼らないコードを作成して下さい。あるいは try...catch で括るなどして、「ニセモノ」として処理されたときのみコードが動作するよう工夫して下さい。あるいはいっそ、XHTML を止めるのも 1 つの選択でしょう。

hosidenshi
質問者

お礼

ご回答ありがとうございました。大変参考になりました。エスケープ処理などわからないことだらけだったのですが、ご回答がきっかけで色々と調べるうちにとても勉強になりました。 結局外部スクリプトにすることで解決しましたが、今後もXHTMLについて一層勉強していきたいと思います。

その他の回答 (2)

  • 4017B
  • ベストアンサー率73% (1337/1815)
回答No.2

多分、下記の様な感じ書けば怒られないと思います?? ━━Sample::start━━━━━━━━━━━━━━━━━━ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ja"> <head> <meta http-equiv="content-language" content="jp" /> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta http-equiv="content-script-type" content="text/javascript" /> <meta http-equiv="content-style-type" content="text/css" /> <title>NowRPG-Systemz.</title> <link rel="index" href="./index.html" /> <link rev="made" href="mailto:aiueo@123.com" /> <script type="text/javascript"> <!-- document.write('<img src=\"http:\/\/w3a\/writelog\.php\?ref='+ document.referrer +'\" width=\"1\" height=\"1\" \/>'); //--> </script> </head> <body> <p>テストです。</p> <noscript> <p>JavaScriptがOFFの時の文書。</p> </noscript> </body> </html> ━━Sample::ebdd━━━━━━━━━━━━━━━━━━ ポイントとしては、 ・XHTMLの書式に乗っ取って書くこと。 ・JavaScript内の文字列扱いの語句をちゃんとエスケープ処理する事。 ~こんな感じでしょうか? 質問文の「<img>を~」とは恐らく。 「document.write('~')」の中の文字列のエスケープ処理がおかしかったからじゃないでしょうか? 別に適当でも動きますが(笑)。 厳密には「/、.、"、'、\、*、-、? (その他演算子)」などは、その文字の前に「\」を置いて“エスケープ処理”をする事が推奨されています。 ですので採点評価サイトなのですから、その辺を厳密に採点してるのだと思います。 後、まさかとは思いますが…。 質問文の「</script> >」は書き損じであって、本物には無いものですよね(文末の“>”が二重)? P.S. 自分的には…  /、.、,、"、'、\、*、-、? 、=、$、&、%、#、!、(、)、{、}、[、]、<、>、;、:、_、^、~、|、@ ~は普段からエスケープ処理する様な癖を付けて置いた方が、後々便利だと思います。

hosidenshi
質問者

お礼

ご回答ありがとうございました。詳しく書いて下さり大変参考になりました。エスケープ処理などわからないことだらけだったのですが、ご回答がきっかけで色々と調べるうちにとても勉強になりました。 結局外部スクリプトにすることで解決しましたが、今後もXHTMLについて一層勉強していきたいと思います。

回答No.1

document.write('<img src="http://~/w3a/writelog.php?ref='+document.referrer+'" width="1" height="1" \/>'); としたらどうですか? 最後を />'); でなくて \/>');

関連するQ&A

専門家に質問してみよう