it-swarm.com.ru

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

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

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

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

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

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

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

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

63
rmeador

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

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

Например,

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

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

.NET 4.0

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

Джава

import org.Apache.commons.lang.StringEscapeUtils;
...

String result = StringEscapeUtils.escapeJavaScript(jsString);

Питон

import json
result = json.dumps(jsString)

PHP

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

Рубин на рельсах

<%= escape_javascript(jsString) %>
20
Vitalii Fedorenko

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

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

10
Shyam

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

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

<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>
9
Kent Fredric

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

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

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

8
Dan

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

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

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

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

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

3
Dan

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

1
moonshadow

Используйте библиотеку Microsoft Anti-XSS , которая включает кодировку JavaScript.

1
blowdart

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

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

</script>

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

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

1
Alexandre Victoor

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

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

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

0
livingtech

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

Следовательно. У JavaScript нет способа справиться со строкой », - сказала Мардж:« Я бы посмотрел, что было »для Питера, и вам нужно очистить свои данные, прежде чем предлагать их сценарию?

0
Steve Perks

Я столкнулся с той же проблемой, и я решил ее хитрым способом. Сначала создайте глобальные переменные 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);
}
0
AhmedGamal