web-dev-qa-db-ja.com

JavaScriptで引用符をエスケープする

データベースから値を出力しています(実際には一般公開されていませんが、会社のユーザーによって公開されています - つまり、私は心配していません 。 _ xss _ 。)

私はこのようなタグを出力しようとしています:

<a href="" onclick="DoEdit('DESCRIPTION');">Click Me</a>

DESCRIPTIONは実際にはデータベースからの値であり、これは次のようなものです。

Prelim Assess "Mini" Report

"\"に置き換えようとしましたが、何をしようと、FirefoxはWordAssessの後のスペースの後にJavaScript呼び出しを切り落とし続けています。問題の.

私は明白な答えを捨て去る必要がありますが、私の人生のために私はそれを理解することはできません。

誰かが私の馬鹿げたことを指摘することを気にかけますか?

これはHTMLページ全体です(最終的には ASP.NET ページになりますが、これを解決するために、問題コード以外はすべて取り除きました)。 )

<html>
    <body>
        <a href="#" onclick="DoEdit('Preliminary Assessment \"Mini\"'); return false;">edit</a>
    </body>
</html>
198
Matt Dawdy

二重引用符を削除するには、書き出す文字列をDoEditにエスケープする必要があります。それらはonclick HTML属性を早めに閉じさせています。

JavaScriptのエスケープ文字\を使用しても、HTMLのコンテキストでは不十分です。二重引用符を適切なXMLエンティティ表現&quot;に置き換える必要があります。

195
Aaron

HTMLコンテキストのため、&quot;はこの特定のケースではうまく機能します。

ただし、JavaScriptコードを任意のコンテキストに対して個別にエスケープする場合は、ネイティブのJavaScriptエンコーディングを選択できます。
'\x27になります
"\x22になります

だからあなたのクリックは次のようになります。
DoEdit('Preliminary Assessment \x22Mini\x22');

これは、たとえばJavaScript文字列をパラメータとして別のJavaScriptメソッドに渡すときにも機能します(alert()はこのための簡単なテストメソッドです)。

重複したスタックオーバーフローの質問を参照しています。onClickハンドラ内のJavaScriptコード内の文字列をエスケープするにはどうすればよいですか?.

88
tsemer
<html>
    <body>
        <a href="#" onclick="DoEdit('Preliminary Assessment &quot;Mini&quot;'); return false;">edit</a>
    </body>
</html>

トリックをするべきです。

33
kristian

皆さん、JavaScriptには既にunescapeという関数があり、これは\"のエスケープ解除を行います。

<script type="text/javascript">
    var str="this is \"good\"";
    document.write(unescape(str))
</script>
23
rohtakdev

問題は、HTMLがエスケープ文字を認識しないことです。 HTML属性には一重引用符を使用し、onclickには二重引用符を使用することでこれを回避できます。

<a href="#" onclick='DoEdit("Preliminary Assessment \"Mini\""); return false;'>edit</a>
12
dl.

これが私のやり方、基本的にはstr.replace(/[\""]/g, '\\"')です。

var display = document.getElementById('output');
var str = 'class="whatever-foo__input" id="node-key"';
display.innerHTML = str.replace(/[\""]/g, '\\"');

//will return class=\"whatever-foo__input\" id=\"node-key\"
<span id="output"></span>
6
Ron Royston

HTMLをJavaで組み立てる場合は、Apache commons-langのこのNiceユーティリティクラスを使用して、すべてのエスケープを正しく実行できます。

org.Apache.commons.lang.StringEscapeUtils
Java、Java Script、HTML、XML、およびSQLの文字列のエスケープとアンエスケープ。

2
iTake

以下のコードで、正規表現を使用して入力文字列の一部として一重引用符をエスケープします。ユーザーが入力した文字列がカンマで区切られているかどうかを検証し、同時に文字列の一部として入力された単一引用符もエスケープします。一重引用符をエスケープするには、バックスラッシュとそれに続く一重引用符を入力します。  文字列の一部として。この例ではJQueryバリデータを使いました。

有効な文字列の例:

'こんにちは'

'こんにちは世界'

'こんにちは世界'

'こんにちは世界'、' '

「それは私の世界だ」、「私なしでは楽しめない」、「ようこそ、ゲスト」

HTML:

<tr>
    <td>
        <label class="control-label">
            String Field:
        </label>
        <div class="inner-addon right-addon">
            <input type="text" id="stringField" 
                   name="stringField"
                   class="form-control"
                   autocomplete="off"
                   data-rule-required="true"
                   data-msg-required="Cannot be blank."
                   data-rule-commaSeparatedText="true"
                   data-msg-commaSeparatedText="Invalid comma separated value(s).">
        </div>
    </td>

JavaScript:

    /**
 * 
 * @param {type} param1
 * @param {type} param2
 * @param {type} param3
 */
jQuery.validator.addMethod('commaSeparatedText', function(value, element) {

    if (value.length === 0) {
        return true;
    }
    var expression = new RegExp("^((')([^\'\\\\]*(?:\\\\.[^\'\\\\])*)[\\w\\s,\\.\\-_\\[\\]\\)\\(]+([^\'\\\\]*(?:\\\\.[^\'\\\\])*)('))(((,)|(,\\s))(')([^\'\\\\]*(?:\\\\.[^\'\\\\])*)[\\w\\s,\\.\\-_\\[\\]\\)\\(]+([^\'\\\\]*(?:\\\\.[^\'\\\\])*)('))*$");
    return expression.test(value);
}, 'Invalid comma seperated string values.');
1
Dinesh Lomte

私はjQueryを使ってサンプルをやった

var descr = 'test"inside"outside';
$(function(){
   $("#div1").append('<a href="#" onclick="DoEdit(descr);">Click Me</a>');       
});

function DoEdit(desc)
{
    alert ( desc );
}

そしてこれはInternet ExplorerとFirefoxで動作します。

1
rahul

これらの2つの関数(以下にリスト)をコピーし、それらを使用してすべての引用符と特殊文字をエスケープ/エスケープできます。このためにjQueryや他のライブラリを使用する必要はありません。

function escape(s) {
return ('' + s) 
    .replace(/\\/g, '\\\\') 
    .replace(/\t/g, '\\t') 
    .replace(/\n/g, '\\n')
    .replace(/\u00A0/g, '\\u00A0') 
    .replace(/&/g, '\\x26') 
    .replace(/'/g, '\\x27')
    .replace(/"/g, '\\x22')
    .replace(/</g, '\\x3C')
    .replace(/>/g, '\\x3E');
 }

function unescape(s) {
 s = ('' + s) 
    .replace(/\\x3E/g, '>')
    .replace(/\\x3C/g, '<')
    .replace(/\\x22/g, '"')
    .replace(/\\x27/g, "'")
    .replace(/\\x26/g, '&') 
    .replace(/\\u00A0/g, '\u00A0') 
    .replace(/\\n/g, '\n')
    .replace(/\\t/g, '\t');

  return s.replace(/\\\\/g, '\\');
}
0
omanosoft

二重のバックスラッシュで引用符をエスケープする必要があります。

これは失敗します(PHPの json_encode によって生成されます)。

<script>
  var jsonString = '[{"key":"my \"value\" "}]';
  var parsedJson = JSON.parse(jsonString);
</script>

これは動作します:

<script>
  var jsonString = '[{"key":"my \\"value\\" "}]';
  var parsedJson = JSON.parse(jsonString);
</script>
0
Buffalo

あなたはescape()とunescape()のjqueryメソッドを使うことができます。

ユーザーエスケープ(str)文字列をエスケープし、unescape(str_esc)を使用して再度回復します。

0
Abhiram

空白もエスケープします。 Firefoxは1つではなく3つの引数を想定しているようです。 &nbsp;は改行なしのスペース文字です。それが問題全体ではないとしても、それはまだ良い考えかもしれません。

0
the Hampster