Escape-кавычки в 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вложение вашего мероприятия ненавязчивым и перенести всю информацию из вашей базы данных на остров данных. Все будет чище, и вы на самом деле получите какую-то синтаксическую ошибку, если ваши строки экранированы неправильно.
Джастин Джонсон


Вы также можете использовать методы jquery escape ("string") и unescape ("string")
Abhiram,

Ответы:


212

Вам нужно экранировать строку, в которую вы пишете, DoEditчтобы вычеркнуть символы двойной кавычки. Они приводят onclickк преждевременному закрытию атрибута HTML.

Использование escape-символа JavaScript, \недостаточно в контексте HTML. Вам нужно заменить двойные кавычки на правильное представление сущности XML &quot;.


Правильно, но разве не так? <a href="#" onclick="DoEdit('Preditional Assessment \"Mini\"'); return false;"> edit </a> Я пытался это сделать, и он все еще не работает. Это должен быть простой WTF, но я не вижу этого.
Мэтт Доуди

Есть ли какая-либо встроенная функция JavaScript, которая будет экранировать двойные кавычки? Кроме 'quo' '. Replace (' '', '& quot;') я ничего не могу найти.
Кевин

4
Это не проблема javascript, это проблема кодирования HTML / XML: внутри значения атрибута нельзя заключать символы в двойные кавычки без их экранирования ... в противном случае браузеры / анализаторы считают, что вы заканчиваете объявление значения атрибута.
Аарон

22
пример замены кода:'mystring'.replace(/"/g, '&quot;');
Джошуа Бернс

3
в предыдущем комментарии есть дополнительная цитата. Работающий код - «mystring» .replace (/ / / g, & quot;);
Агустин Лопес

95

&quot; будет работать в этом конкретном случае, как предлагалось до меня, из-за контекста HTML.

Однако, если вы хотите, чтобы ваш код JavaScript был независимо экранирован для любого контекста, вы можете выбрать нативную кодировку JavaScript:
'становится \x27
"становится\x22

Так что ваш клик станет:
DoEdit('Preliminary Assessment \x22Mini\x22');

Это будет работать, например, также при передаче строки JavaScript в качестве параметра другому методу JavaScript ( alert()это простой метод тестирования для этого).

Я имею в виду повторяющийся вопрос переполнения стека: как мне избежать строки внутри кода JavaScript внутри обработчика onClick?,


2
Спасибо! Ваш правильный ответ, потому что это родной JavaScript, независимо от контекста.
scarver2

2
Это правильный ответ, хотя в контексте HTML использование &quot;, конечно, будет работать.
Оливер

Обратите внимание, что &quot;требуется во входных значениях, т. <input value="\x22quoted string\x22">Е. Не будет работать.
thdoan

@ 10basetom, естественно, экранирование JavaScript работает только в контексте JavaScript, как обработчики событий ( onclick="..."). Значение valueатрибута не обрабатывается в контексте JavaScript, а только в контексте HTML.
Цемер

Код замены:'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
Комбинация «побег» / «unescape» сделала то, что мне нужно. Спасибо.
Луис Р.

8
escape / unescape устарели. хотя encodeURI делает больше, чем просто кавычки. gotochriswest.com/blog/2011/05/23/escape-unescape-deprecated
chug2k

12

Проблема в том, что HTML не распознает escape-символ. Вы можете обойти это, используя одинарные кавычки для атрибута HTML и двойные кавычки для щелчка.

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

5
Хлоп. Мне было интересно, почему я естественным образом прибегнул к использованию атрибута в прошлом. Я просто никогда не углублялся в это все так глубоко. Спасибо.
Мэтт Доуди

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

Если вы собираете HTML-код в Java, вы можете использовать этот полезный служебный класс из Apache commons-lang, чтобы сделать все экранирование правильно:

org.apache.commons.lang.StringEscapeUtils
Экранирует и освобождает строки для Java, Java Script, HTML, XML и SQL.


Я использую org.apache.commons.lang3.StringEscapeUtils.escapeEcmaScript (text) для создания метода Expression в Java. Спасибо.
Харун

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") .... Менее чем оптимально, но спасибо за предложение.
Мэтт Доуди

1

Вы можете скопировать эти две функции (перечислены ниже) и использовать их для экранирования / удаления всех кавычек и специальных символов. Вам не нужно использовать 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 предполагает три аргумента вместо одного. &nbsp;это неразрывный пробел Даже если это не вся проблема, это все равно может быть хорошей идеей.


0

Вы должны избегать кавычек с двойной обратной косой чертой.

Это терпит неудачу (произведено json_encode PHP ):

<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

Вы можете использовать методы jQuery escape () и unescape (). Как ниже,

Используйте escape(str);для выхода из строки и восстановления снова, используя unescape(str_esc);.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.