JavaScriptでの引用符のエスケープ


211

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

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

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

DESCRIPTIONは、実際には次のようなデータベースの値です。

Prelim Assess "Mini" Report

私は「\と」交換しようとしましたが、私がしようとするものに関係なくは、Firefoxは単語の後のスペースの後に私のJavaScript呼び出しをオフにチョッピング続け評価し、それが問題のすべての種類を引き起こしています。

私は明白な答えを逃しているに違いありませんが、私の人生ではそれを理解することはできません。

誰かが私の愚かさを指摘して気にかけますか?

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

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

3
onclickイベントの添付ファイルを目立たなくし、すべてのデータベース情報をデータアイランドに移動することをお勧めします。物事はよりきれいになり、文字列が誤ってエスケープされると、実際には何らかの構文エラーが発生します。
ジャスティンジョンソン、


また、escape( "string")およびunescape( "string")jqueryメソッドを使用することもできます
Abhiram

回答:


212

DoEdit二重引用符の文字を削除するには、書き込み中の文字列をエスケープする必要があります。これにより、onclickHTML属性が途中で終了します。

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


ね、でもこれじゃないの?<a href="#" onclick="DoEdit('Preliminary Assessment \"Mini\"'); return false;"> edit </a>試してみましたが、それでも問題が解決しません。これは単純なWTFである必要がありますが、私の人生では、それを見ることができません。
Matt Dawdy、2010年

二重引用符をエスケープする組み込みのJavaScript関数はありますか?'quo' '。replace(' "'、'&quot; ')以外は何も見つかりません。
ケビン

4
これはJavaScriptの問題ではなく、HTML / XMLのエンコーディングの問題です。エスケープせずに属性値内に二重引用符を含めることはできません。それ以外の場合、ブラウザー/パーサーは属性値宣言を終了していると見なします。
アーロン

22
置換コードの例:'mystring'.replace(/"/g, '&quot;');
Joshua Burns

3
前のコメントには、追加の引用があります。機能するコードは 'mystring'.replace(/' / g、 '&quot;');です。
アグスティンロペス

95

&quot; 私の前に提案したように、HTMLコンテキストのため、この特定のケースで機能します。

あなたがJavaScriptコードは独立して任意のコンテキストのためにエスケープするしたい場合は、ネイティブのJavaScriptのエンコーディングを選ぶことができます:
'なり\x27
"なり\x22

したがって、onclickは次のようになります。
DoEdit('Preliminary Assessment \x22Mini\x22');

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

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


2
ありがとうございました!Yoursは、コンテキストに関係なくネイティブJavaScriptなので、正解です。
scarver2

2
これは正解ですが、HTMLのコンテキストで&quot;は、もちろんは機能します。
オリバー

&quot;入力値には必須である、つまり機能し<input value="\x22quoted string\x22">ないことに注意してください。
thdoan 2018年

@ 10basetom当然、JavaScriptエスケープは、イベントハンドラー(onclick="...")などのJavaScriptコンテキストでのみ機能します。value属性の値はJavaScriptコンテキスト内では処理されず、HTMLコンテキスト内でのみ処理されます。
tsemer

置換コード:'mystring'.replace(/"/g, '\\x22').replace(/'/g, '\\x27')
ニワトリ

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

トリックを行う必要があります。


24

unescape皆さん、JavaScript にはすでにエスケープ解除を行う関数があります\"

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

2
「escape」/「unescape」の組み合わせで、私が必要とすることを実現しました。ありがとう。
Luis R.

8
escape / unescapeは非推奨です。ただし、encodeURIは引用符だけではありません。gotochriswest.com/blog/2011/05/23/escape-unescape-deprecated
chug2k

12

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

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

5
うわぁ。なぜ私は過去に属性に 'を使用することに自然に訴えたのかと思っていました。そんなに深く掘り下げたことはありません。ありがとう。
Matt Dawdy、2010年

6

これが基本的なやり方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>


2

JavaでHTMLをアセンブルしている場合は、Apache commons-langのこの便利なユーティリティクラスを使用して、すべてのエスケープを正しく行うことができます。

org.apache.commons.lang.StringEscapeUtils
Java、Java Script、HTML、XML、およびSQLの文字列をエスケープおよびエスケープ解除します。


私はorg.apache.commons.lang3.StringEscapeUtils.escapeEcmaScript(text)を使用してJavaでmethodExpressionを構築しています。ありがとう。
Harun

1

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で動作します。


5
もちろん、属性に直接入れていないためです。あなたのメソッドを使用するには、JS文字列の配列を作成してから、任意の数の$( "#divxxx")...割り当てを行う必要があります。最適ではありませんが、提案に感謝します。
Matt Dawdy、2010年

1

これら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, '\\');
}

1

正規表現を使用して入力した文字列の一部として一重引用符をエスケープする以下のコードを見つけてください。ユーザーが入力した文字列がカンマで区切られているかどうかを検証し、同時に文字列の一部として入力された単一引用符もエスケープします。

単一引用符をエスケープするには、バックスラッシュを入力し、文字列の一部として\ 'のように単一引用符を続けます。この例では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 separated string values.');

0

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


0

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

これは失敗します(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

escape()およびunescape()jQueryメソッドを使用できます。以下のように、

escape(str);文字列をエスケープし、を使用して再度回復するために使用しunescape(str_esc);ます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.