Как избежать строки внутри кода JavaScript внутри обработчика onClick?

Возможно, я просто слишком много думал об этом, но у меня возникли проблемы с выяснением того, что можно использовать для строки в некотором JavaScript-коде внутри обработчика onClick. Пример:

<a href="#" onclick="SelectSurveyItem('<%itemid%>', '<%itemname%>'); return false;">Select</a>

<%itemid%> и <%itemname%> заключаются в замене шаблона. Моя проблема в том, что имя элемента может содержать любой символ, включая одиночные и двойные кавычки. В настоящее время, если он содержит одинарные кавычки, он разбивает код JavaScript.

Моя первая мысль заключалась в том, чтобы использовать функцию языка шаблонов для JavaScript-escape имя элемента, которое просто ускользает от котировок. Это не будет фиксировать случай строки, содержащей двойные кавычки, которая нарушает HTML ссылки. Как обычно эта проблема рассматривается? Мне нужно, чтобы HTML-escape весь обработчик onClick?

Если это так, это выглядело бы странно, потому что функция escape-драйва для шаблона также могла бы кодировать скобки, кавычки и точки с запятой...

Эта ссылка создается для каждого результата на странице результатов поиска, поэтому создание отдельного метода внутри тега JavaScript невозможно, потому что мне нужно будет генерировать по одному на результат.

Кроме того, я использую шаблонный движок, который был доморощенным в компании, в которой я работаю, поэтому конкретные решения для инструментария будут бесполезны для меня.

Ответ 1

В JavaScript вы можете кодировать одинарные кавычки как "\ x27" и двойные кавычки как "\ x22". Поэтому с помощью этого метода вы можете, когда вы находитесь внутри (двойных или одиночных) кавычек строкового литерала JavaScript, используйте \x27\x22 с безнаказанностью, не опасаясь каких-либо встроенных кавычек, "вырывающих" вашу строку.

\ xXX для символов < 127 и \uXXXX для Unicode, поэтому, вооружившись этими знаниями, вы можете создать надежную функцию JSEncode для всех символов, которые не соответствуют обычным Белый список.

Например,

<a href="#" onclick="SelectSurveyItem('<% JSEncode(itemid) %>', '<% JSEncode(itemname) %>'); return false;">Select</a>

Ответ 2

В зависимости от серверного языка вы можете использовать один из них:

.NET 4.0

string result = System.Web.HttpUtility.JavaScriptStringEncode("jsString")

Java

import org.apache.commons.lang.StringEscapeUtils;
...

String result = StringEscapeUtils.escapeJavaScript(jsString);

Python

import json
result = json.dumps(jsString)

PHP

$result = strtr($jsString, array('\\' => '\\\\', "'" => "\\'", '"' => '\\"', 
                                 "\r" => '\\r', "\n" => '\\n' ));

Ruby on Rails

<%= escape_javascript(jsString) %>

Ответ 3

Используйте скрытые интервалы, по одному для каждого из параметров <%itemid%> и <%itemname%>, и записывайте их значения внутри них.

Например, диапазон для <%itemid%> будет выглядеть как <span id='itemid' style='display:none'><%itemid%></span> и в функции javascript SelectSurveyItem для выбора аргументов из этих интервалов innerHTML.

Ответ 4

Попробуйте избегать использования строковых литералов в вашем HTML и использовать JavaScript для привязки событий JavaScript.

Кроме того, избегайте 'href= #', если вы действительно не знаете, что делаете. Это ломает так много удобства для компульсивного middleclickers (вкладка).

<a id="tehbutton" href="somewhereToGoWithoutWorkingJavascript.com">Select</a>

Моя библиотека JavaScript по выбору просто оказывается jQuery:

<script type="text/javascript">//<!-- <![CDATA[
jQuery(function($){
   $("#tehbutton").click(function(){
        SelectSurveyItem('<%itemid%>', '<%itemname%>');
        return false;
   });
});
//]]>--></script>

Если вам удастся отобразить список таких ссылок, вы можете сделать это:

<a id="link_1" href="foo">Bar</a>
<a id="link_2" href="foo2">Baz</a>

<script type="text/javascript">
   jQuery(function($){
        var l = [[1,'Bar'],[2,'Baz']];
        $(l).each(function(k,v){
           $("#link_" + v[0] ).click(function(){
                SelectSurveyItem(v[0],v[1]);
                return false;
           });
        });
   });
 </script>

Ответ 5

Если он входит в атрибут HTML, вам нужно как HTML-кодировать (как минимум: > до &gt; < до &lt и " до &quot;)), и избегать одиночных кавычек (с обратной косой чертой), поэтому они не мешают вашему цитированию javascript.

Лучший способ сделать это - с помощью вашей системы шаблонов (при необходимости продлить ее), но вы можете просто сделать пару функций экранирования/кодирования и обернуть их как вокруг любых данных, которые там будут.

И да, это совершенно верно (правильно, даже) для HTML-избежать всего содержимого ваших HTML-атрибутов, даже если они содержат javascript.

Ответ 6

Другим интересным решением может быть это:

<a href="#" itemid="<%itemid%>" itemname="<%itemname%>" onclick="SelectSurveyItem(this.itemid, this.itemname); return false;">Select</a>

Затем вы можете использовать стандартную HTML-кодировку для обеих переменных, не беспокоясь о дополнительном усложнении цитирования javascript.

Да, это создает HTML, который строго недействителен. Однако это эффективный метод, и все современные браузеры поддерживают его.

Если бы это был мой, я бы, вероятно, пошел с моим первым предложением и гарантировал, что значения закодированы в HTML и имеют одиночные кавычки.

Ответ 7

Объявить отдельные функции в <head> и вызывать их в методе onClick. Если у вас есть лоты, вы можете использовать схему именования, которая их числивает, или передать целое число в вашем onClicks и иметь большой оператор переключения жира в функции.

Ответ 9

Во-первых, было бы проще, если бы обработчик onclick был установлен следующим образом:

<a id="someLinkId"href="#">Select</a>
<script type="text/javascript">
  document.getElementById("someLinkId").onClick = 
   function() {
      SelectSurveyItem('<%itemid%>', '<%itemname%>'); return false;
    };

</script>

Затем itemid и имя элемента должны быть экранированы для JavaScript (т.е. " становится \" и т.д.).

Если вы используете Java на стороне сервера, вы можете взглянуть на класс StringEscapeUtils из jakarta common-lang. В противном случае не нужно слишком долго писать собственный метод "escapeJavascript".

Ответ 10

Я столкнулся с этой проблемой. Я сделал script для преобразования одиночных кавычек в скрытые двойные кавычки, которые не будут нарушать HTML.

function noQuote(text)
{
    var newtext = "";
    for (var i = 0; i < text.length; i++) {
        if (text[i] == "'") {
            newtext += "\"";
        }
        else {
            newtext += text[i];
        }
    }
    return newtext;
}

Ответ 11

Здесь ответы, что вы не можете избежать кавычек с использованием JavaScript и что вам нужно начать с экранированных строк.

Поэтому. Там нет способа, которым JavaScript мог обрабатывать строку "Мардж сказал". Я бы посмотрел, что это был "Питер", и вам нужно, чтобы ваши данные были очищены, прежде чем предлагать его script?

Ответ 12

Любой хороший шаблонный двигатель, стоящий на его соли, будет иметь функцию "escape quotes". Наш (также доморощенный, где я работаю) также имеет функцию, чтобы избежать кавычек для javascript. В обоих случаях переменная шаблона затем просто добавляется с помощью _esc или _js_esc, в зависимости от того, что вы хотите. Вы никогда не должны выводить созданный пользователем контент в браузер, который не был экранирован, IMHO.

Ответ 13

У меня возникла такая же проблема, и я решил это непросто. Сначала создайте глобальные переменные v1, v2 и v3. И в onclick отправьте индикатор 1, 2 или 3 и в функции проверьте 1, 2, 3, чтобы поместить v1, v2 и v3, например:

onclick="myfun(1)"
onclick="myfun(2)"
onclick="myfun(3)"

function myfun(var)
{
    if (var ==1)
        alert(v1);

    if (var ==2)
        alert(v2);

    if (var ==3)
        alert(v3);
}