Втечі котирування в JavaScript


211

Я виводжу значення з бази даних (вона насправді не відкрита для публічного входу, але вона відкрита для входу користувачем компанії - це означає, що я не переживаю за XSS ).

Я намагаюся вивести такий тег:

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

ОПИС - це фактично значення бази даних, яке є приблизно таким:

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 закриватися передчасно.

Використання символу втечі JavaScript, \недостатньо в контексті HTML. Ви повинні замінити подвійні лапки з відповідним поданням XML - об'єкта, &quot;.


Правильно, але хіба це не було б? <a href="#" onclick="DoEdit('Попередня оцінка \"Mini\"'); повернути помилкові ;"> редагувати </a> Я спробував це, і він все ще вивертається. Це повинно бути простим WTF, але все життя я цього не бачу.
Метт Дауді

Чи є якась вбудована функція JavaScript, яка б уникнула подвійних лапок? Крім 'quo' '. Substitute (' "',' & quot; ') я нічого не можу знайти.
кевін

4
Це не проблема JavaScript, це проблема кодування HTML / XML: ви не можете мати подвійні цитати символів у значенні атрибутів, не уникаючи їх ... інакше браузери / аналізатори думають, що ви закінчуєте декларацію про значення атрибута.
Аарон

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

3
в попередньому коментарі є додаткова цитата. Код, який працює, - 'mystring'.replace (/' / g, '& quot;');
Агустін Лопес

95

&quot; У цьому конкретному випадку, як було запропоновано раніше, буде працювати в зв'язку з контекстом HTML.

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

Таким чином, ваш onclick став би:
DoEdit('Preliminary Assessment \x22Mini\x22');

Це може працювати, наприклад, також при передачі рядка JavaScript в якості параметра іншому методу JavaScript ( alert()це простий метод тестування для цього).

Я маю на увазі вас із дублюючим запитанням про переповнення стека: Як я уникну рядок всередині коду JavaScript всередині обробника onClick? .


2
Дякую! Ваша правильніша відповідь, оскільки це рідний JavaScript незалежно від контексту.
scarver2

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

Зверніть увагу, що &quot;потрібно у вхідних значеннях, тобто <input value="\x22quoted string\x22">не буде працювати.
thoan

@ 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
Поєднання «втеча» / «невидимка» зробило те, що мені потрібно. Дякую.
Луїс Р.

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
Yikes. Мені було цікаво, чому я природно вдався до використання атрибута "раніше". Я просто ніколи не заглиблювався в це все так глибоко. Дякую.
Метт Дауді

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 (текст) для побудови методу 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.