JavaScriptを使っていると、レアな確率で遭遇するトラブル・・・
それは文字列内でscriptタグが書けないという厄介な問題
多分「なにそれ?初めて聞いた」という人も多いと思います。でも、スクリプト内でさらにスクリプトを呼びたいときに遭遇することが稀によくあります。
ということで文字列内でscript閉じタグが書けない対処法をまとめました。
このページの目次
文字列内でscriptタグを使うときの厄介な問題
冒頭でも書いたように、これは文字列内とかで scriptタグ を書いたときに起きる問題
少し例を出して、どういう状況なのか説明してみます。
例えば次みたいに、何の変哲もないJSコードを書いたとしましょう。
1 2 3 4 5 6 7 |
<script> var script = ` <script> alert('script in script'); </script> `; </script> |
上のコード例だとテンプレートリテラルを使って複数行の文字列定義してます、
参考記事 ⇒ JavaScriptで複数行文字列を代入する一番簡単な方法
普通に考えれば「当然動くに決まってるだろwww」って思うはず
でも残念、このコードは動きません。次のようなエラーが出てしまいます。
1 |
Uncaught SyntaxError: Unexpected end of input |
自分は初めてこのエラーに遭遇したときは、
え?なんで?どこか間違ってる?
みたいにかなりビックリしました。だって間違えてそうな所がないんだから
でも上コードをよ~く見てみてください。何か気づきませんか?
そう、文字列内で scriptタグ を使ってるんです。
エラーになってる原因は、scriptの閉じタグですね。次のハイライトした部分がそれ
1 2 3 4 5 6 7 |
<script> var script = ` <script> alert('script in script'); </script> `; </script> |
文字列内の </script> がその外にある </script> より優先されて解釈される・・・
これがエラーが出てしまう原因だった模様
自分もこの原因が分からず、何時間も悩み続けたことがありました。
でもこのscriptタグ問題の解決方法は簡単です。次で紹介するみたいに3つの解決策があります。
文字列でscriptタグが書けない問題の3つの対処法
このscriptタグ(特に終わりタグ)が文字列内で直書きできない問題
この問題に対して、自分がよく使ってる回避策は次の3つです。
1.< と /scrip> を + でつなぎ区切って書く
まず1つめの解決策がコレ
文字列内のscriptタグを区切って書いてあげるというやり方
単純に文字列の </script> を < と /script> に分けて書けばいいだけです。
一応コード例を載せておくと、こういう感じ
1 2 3 4 5 |
var script = ` <script> alert('script in script'); <` + `/script> `; |
うん・・・説明するまでもないくらい簡単
こっちは可読性は少し下がるけど確実な方法ですね。
もちろん </ と script> とかで分けてもいいです。
とりあえず1つの文字列リテラルに </script> が含まれてなければOK
2.コードをHTMLコメントで囲むという回避策
次は文字列でscriptタグを定義してるコードをHTMLコメントで囲むという回避策
僕自身もつい最近まで知らなかったので「へぇ~」と思いました。
やり方は次みたいに /*<!--*/ と /*-->*/ で問題のあるコードを囲むだけ
1 2 3 4 5 6 7 8 9 |
<script> /*<!--*/ var script = ` <script> alert('script in script'); </script> `; /*-->*/ </script> |
この書き方って元々JavaScriptを実行できないブラウザ用の回避策だった模様
でも今回みたいに、文字列で表現できないタグとかをエスケープするのにも使えます。
ちなみに、次みたくHTMLコメントだけで書いても問題ありません。
1 2 3 4 5 6 7 8 9 |
<script> <!-- var script = ` <script> alert('script in script'); </script> `; --> </script> |
ちなみにこの書き方、本題と全く関係ないけど、
- w3m
- Lynx
みたいなテキストブラウザ用の措置に使われてたみたいです。
あとJSコードを解釈できないクローラー用とかにも
3.スラッシュを \ でエスケープする方法
最後は scriptタグ のスラッシュをバックスラッシュでエスケープするという回避策
要は文字列内の </script> を <\/script> みたいにエスケープするってことです。
ただしこの方法はテンプレート文字列では使えないことに注意
シングルクォート( ' )またはダブルクォート( " )で文字列定義してる場合だけ使える方法です。
これもコード例的なのを載せておくと次の通り
1 2 3 4 5 6 7 8 9 10 11 |
/// シングルクォートの場合 var script = "<script>" + " alert('script in script');" + "<\/script>"; /// ダブルクォートの場合 var script = '<script>' + ' alert("script in script");' + '<\/script>'; |
上コードみたいな感じ
こっちは + で結ぶのと比べると、かなり可読性が下がっちゃいますね。
でも一応こういうやり方もあるよ、という意味で紹介しておきます。
ここまでのまとめ
JavaScriptの文字列内で scriptタグ を書く方法をまとめると次の通り
- 文字列内の < と /script> を + で連結する
一続きではなく部分部分に区切って + で結ぶ方法。一番簡単な回避策かも
- コードをHTMLコメントで囲む
問題箇所を /*<!--*/ と /*-->*/ で囲む。元々はテキストブラウザへの措置だった模様
- スラッシュを \ でエスケープする
script終わりタグを <\/script> でエスケープするやり方。あんまり読みやすくない...
以上、JavaScriptの文字列内でscriptタグが書けないときの対処法でした。ではでは(^_^)/~