web-dev-qa-db-ja.com

JavaScriptからHTMLを生成するときに、<の代わりに\ x3Cを使用するのはなぜですか?

次のHTMLコードは、コンテンツ配信ネットワークからjQueryをロードするために多く使用されていますが、CDNが利用できない場合はローカルコピーにフォールバックします(例: Modernizr docs ):

_<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.1.min.js">\x3C/script>')</script>
_

私の質問は、document.write()ステートメントの最後の_<_文字がエスケープシーケンス_\x3C_に置き換えられるのはなぜですか? _<_はJavaScriptの安全な文字であり、同じ文字列で以前に使用されていたのに、なぜそこでエスケープするのですか?文字列内の_</script>_が実際のスクリプトの終了タグであると考えないようにするために、ブラウザの実装が間違っているのでしょうか?もしそうなら、これで失敗するブラウザは本当にありますか?

続く質問として、私はunescape()この回答 で与えられている)を実際に使用しているバリアントも数回見ました。そのバージョンが常にall_<_および_>_文字に置き換わっているように見える理由はありますか?

29
Mark Whitaker

ブラウザーは</script>を認識すると、これをスクリプトブロックの終わりと見なします(HTMLパーサーはJavaScriptを認識していないため、文字列に表示されるだけのものと実際にはスクリプト要素を終了することを意味します)。したがって、HTMLページ内にあるJavaScriptに文字通り</script>が表示されると、(最良の場合)エラーが発生し、(最悪の場合)大きなセキュリティホールになります。

そのため、この一連の文字が表示されないようにする必要があります。この問題の他の一般的な回避策は、"<"+"/script>""<\/script>"です(これらはすべて同じものになります)。

これを「バグ」と考える人もいますが、実際には仕様 のように、このようにして発生する必要があります。 、ユーザーエージェントのHTML部分は、スクリプトエンジンから完全に分離されています。 JavaScriptだけでなく、あらゆる種類のものを<script>タグに入れることができます。 W3Cでは、例としてVBScriptとTCLについて言及しています。別の例は jQueryテンプレートプラグイン で、これらのタグも使用します。

しかし、JavaScript内でさえ、文字列内のそのようなコンテンツが認識され、終了タグとして扱われない可能性があることを示唆する可能性がある場合、コメントを検討すると次のあいまいさが生じます。

<script type="text/javascript">foo(42); // call the function </script>

–この場合、ブラウザは何をすべきですか?

そして最後に、JavaScriptさえ知らないブラウザはどうですか? <script></script>の間の部分は無視されますが、JavaScriptのブラウザの知識に基づいて文字シーケンス</script>に異なるセマンティクスを与えた場合HTML解析ステージで突然2つの異なる結果が得られます。

最後に、all山括弧の置換に関する質問について:少なくとも99%のケースでは、難読化、つまり非表示にする(アンチウイルスソフトウェア、検閲プロキシ(あなたの例のように(ネストされた親は素晴らしいです))などから)JavaScriptがHTMLのようなことをしているという事実。少なくとも合理的に最新のブラウザでは、</script>以外のものを非表示にするための技術的な理由は考えられません(つまり、Mosaicよりも新しいものを意味します)。

56
balpha

一部のパーサーは、<バージョンを終了タグとして扱い、コードを次のように解釈します。

<script>
  window.jQuery || document.write('<script src="js/libs/jquery-1.6.1.min.js">
</script>

\x3C<の16進数です。これらはスクリプト内で交換可能です。

2
J. K.