7786


・他言語(PHP)から渡した内容を、JavaScriptで文字列として受け取りたいです  
・渡す内容には、HTMLタグ、改行、""などが含まれているため、現状では文法エラーになります

・JavaScriptで文字列として受け取るためには、どういう風にエスケープすれば良いでしょうか？  
(障害になるものは全て削除して構わないです)  
・受け取る側のJavaScriptではなく、渡す側のPHPで処理した方が良いのでしょうか？


CC BY-SA 3.0
2015-03-11T09:30:28.270
7785
2015-04-19T00:11:37.137
7886
question
javascript
JavaScriptで文字列として受け取るため、エスケープしたい


手っ取り早いのは文字列を`JSON`に変換してしまう方法です。

[code]

    <?php 
    
    $str = <<<EOD
    <div>
        <a href="example.com"></a>
    </div>
    EOD;
    
    echo json_encode([$str]); // => ["<div>\n\t<a href=\"example.com\"><\/a>\n<\/div>"]
    
[/code]

[code]

    var str = "<div>\n\t<a href=\"example.com\"><\/a>\n<\/div>";
    alert(str);
[/code]


CC BY-SA 3.0
2015-03-11T09:41:40.367
7786
2015-03-11T09:47:02.663
2015-03-11T09:47:02.663
3639
3639
7785
answer


タグが不要なのであれば、タグの除去は`strip_tags`でPHPでやるのが良いと思います。  
ダブルクォーテーションや改行はどっちにしろ置換処理などで削除が必要だと思いますのでJavaScriptの`replace`でも良いんじゃないでしょうか。

別にタグがあっても良いのであれば`jQuery`で`text()`を使えば無効化できます。

[code]

    $(document).ready(function(){
        
        $('input').on('keyup', function(e){
            $('span').text($(this).val());
        });
        
    });
[/code]

[code]

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    
    <p>タグでもなんでも入れてください。</p>
    <p>入力：<input /></p>
    <p>出力：<span></span></p>
[/code]


CC BY-SA 3.0
2015-03-11T10:26:54.327
7791
2015-03-11T10:26:54.327
7214
7785
answer


プログラムからjavascriptのプログラム中に文字列を埋め込むにはエスケープが大変なので避けるべきとされています。(理由は後で)

そこで、htmlの属性値にデータを書き出しておいて、DOM経由でデータを受け取るのが良いでしょう。これであればhtmlとしてvalidな文字列してエスケープするだけで(ほぼ)安全にデータを受け渡しできます。

[code]

    <html>
      <body>
      <?php $a = "abcdefg" ?>
      <input id="hoge" type="hidden" value="<?php echo htmlentities($a, ENT_QUOTES, 'UTF-8') ?>"></div>
      <script type="text/javascript">
         var str = document.getElementById('hoge').value
         alert(str);
      </script>
    
      </body>
    </html>
    
[/code]

* * *
[code]

    <script>   
        var str = '<?php echo 何らかのescape($str) ?>';
    </script>
    
[/code]

という形でデータを受け渡すには、javascriptとしてvalidであることに加え、HTMLの構造を壊さないようにする必要があります。たとえば出力文字列中に`</`が含まれているとそこでscript要素が終了してしまいますが、そういうことに配慮していることが仕様上保証されている(上記のような使い方をしても良いと明記されている)escape関数でないかぎり、そのような使い方をしてはいけません。


CC BY-SA 3.0
2015-03-19T05:57:16.520
8106
2015-03-19T05:57:16.520
5793
7785
answer


正論がすでに出ていますが、ちょっとひねくれた解を。  
タグなど引っかかってしまう文字をHTMLの`特殊文字`に変換したらどうでしょう。  
例えば、`<`を`&lt;`に、`>`を`&gt;`に変換します。「HTML 特殊文字」などの言葉でググれば、一覧がたくさん出てきます。


CC BY-SA 3.0
2015-04-18T12:16:11.673
9287
2015-04-18T12:16:11.673
8505
7785
answer


Rails の場合、`json_escape` が用意されており、オブジェクトを直接生成できます。JSON に変換した上で U+0026
(&)、U+003C (<)、U+003E (>)、U+2028、U+2029 (改行) がエスケープされることがマニュアルに明記されています。

[code]

    <script>
    var currentUser = <%= raw json_escape(current_user.to_json) %>;
    </script>
    
[/code]

PHP であれば、`json_encode` にエスケープオプションを指定します。

[code]

    <?php
    function json_escape(array $array)
    {
        return json_encode(
             $array,
             JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT
        );
    }
    
    $data = ['foo' => 'bar'];
    ?>
    
    <script>
    var data = <?= json_escape($data) ?>;
    </script>
    
[/code]

WordPress の場合、`wp_localize_script` で JavaScript のオブジェクトを生成できますが、回答時点では HTML
の特殊文字などはエスケープされないので、不特定多数のユーザーからの入力を扱う場合、自前のエスケープが必要になります。


CC BY-SA 3.0
2015-04-19T00:11:37.137
9295
2015-04-19T00:11:37.137
568
7785
answer