Como faço para escapar de uma corda dentro do código JavaScript dentro de um manipulador onClick?
-
01-07-2019 - |
Pergunta
Talvez eu esteja apenas pensando sobre isso muito difícil, mas eu estou tendo um problema descobrir o que escapar para usar em uma corda em algum código JavaScript dentro manipulador onClick de um link. Exemplo:
<a href="#" onclick="SelectSurveyItem('<%itemid%>', '<%itemname%>'); return false;">Select</a>
O <%itemid%>
e <%itemname%>
são onde ocorre a substituição do modelo. Meu problema é que o nome do item pode conter qualquer caractere, incluindo aspas simples e duplas. Atualmente, se contiver aspas simples ele quebra o código JavaScript.
Meu primeiro pensamento era usar a função do modelo de linguagem para JavaScript escapar-o nome do item, o que só escapa as aspas. Isso não vai resolver o caso da cadeia contendo aspas duplas que quebra o HTML do link. Como é este problema normalmente abordadas? Preciso HTML-escapar a toda onClick manipulador?
Se assim for, que ficaria muito estranho desde função de escape do modelo de linguagem para que também HTMLify os parênteses, aspas e vírgulas ...
Este link está sendo gerado para cada resultado em uma página de resultados de pesquisa, de modo a criar um método separado dentro de uma tag JavaScript não é possível, porque eu preciso gerar um por resultado.
Além disso, estou usando um motor de templates que foi home-grown no trabalho da empresa I para, pelo que as soluções específicas-toolkit será de nenhuma utilidade para mim.
Solução
Em JavaScript você pode codificar aspas simples como "\ x27" e aspas duplas como "\ x22". Portanto, com este método, você pode, uma vez que está dentro das aspas (casal ou solteiro) de uma string literal JavaScript, use o \ x27 \ x22 impunemente, sem medo de qualquer cotações incorporadas "quebrando out" de sua corda.
\ XXX é para caracteres <127, e \ uXXXX para Unicode , tão armado com esta conhecimento que você pode criar uma robusta JSEncode função para todos os caracteres que estão fora da lista branca de costume.
Por exemplo,
<a href="#" onclick="SelectSurveyItem('<% JSEncode(itemid) %>', '<% JSEncode(itemname) %>'); return false;">Select</a>
Outras dicas
Dependendo do idioma do lado do servidor, você pode usar um destes:
.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) %>
vãos Use escondidos, cada um para cada um dos parâmetros <%itemid%>
e <%itemname%>
e escrever seus valores dentro deles.
Por exemplo, o tempo para <%itemid%>
seria semelhante <span id='itemid' style='display:none'><%itemid%></span>
e na SelectSurveyItem
função javascript para escolher os argumentos de innerHTML
desses vãos.
Tente evitar o uso de cordas-literais em seu HTML e usar JavaScript para vincular eventos de JavaScript.
Além disso, evitar 'href = #' a menos que você realmente sabe o que está fazendo. Ele quebra tanto a usabilidade para middleclickers compulsivo (guia abridor).
<a id="tehbutton" href="somewhereToGoWithoutWorkingJavascript.com">Select</a>
biblioteca Meu JavaScript de escolha só acontece de ser jQuery:
<script type="text/javascript">//<!-- <![CDATA[
jQuery(function($){
$("#tehbutton").click(function(){
SelectSurveyItem('<%itemid%>', '<%itemname%>');
return false;
});
});
//]]>--></script>
Se acontecer de você ser tornando uma lista de links como esse, você pode querer fazer isso:
<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>
Se ele vai para um atributo HTML, você precisa tanto HTML-codificar (no mínimo: >
para >
<
para <
e "
para "
)-lo, e escapar aspas simples (com uma barra invertida) para que eles não interfiram com o seu javascript citando.
A melhor maneira de fazer isso é com o seu sistema de templates (estendendo-o, se necessário), mas você poderia simplesmente fazer um par de escapar / codificação de funções e envolvê-los ambos em torno de quaisquer dados que está acontecendo lá dentro.
E sim, é perfeitamente válido (correta, mesmo) para HTML-escape todo o conteúdo de seus atributos HTML, mesmo que contenham javascript.
Outra solução interessante seria fazer isso:
<a href="#" itemid="<%itemid%>" itemname="<%itemname%>" onclick="SelectSurveyItem(this.itemid, this.itemname); return false;">Select</a>
Em seguida, você pode usar um padrão em ambas as variáveis, sem ter que se preocupar com a complicação extra do javascript citando-codificação HTML.
Sim, esta faz criar HTML que é estritamente inválido. No entanto, ele é uma técnica válida, e todos os navegadores modernos apoiá-lo.
Se fosse minha, eu provavelmente ir com a minha primeira sugestão, e garantir que os valores são codificado em HTML e tem aspas simples escapou.
Declare funções distintas na seção
e invocar aqueles em seu método onClick. Se você tem um monte você poderia usar um esquema de nomeação que os números deles, ou passar um inteiro no em seus onClicks e ter uma declaração grande mudança de gordura na função.Eu enfrentei esse problema também. Fiz um script para converter aspas simples em aspas duplas escaparam que não vai quebrar o código HTML.
function noQuote(text)
{
var newtext = "";
for (var i = 0; i < text.length; i++) {
if (text[i] == "'") {
newtext += "\"";
}
else {
newtext += text[i];
}
}
return newtext;
}
Use o Microsoft Anti-XSS biblioteca que inclui uma codificação JavaScript.
Em primeiro lugar, seria mais simples se o manipulador onclick foi definido desta maneira:
<a id="someLinkId"href="#">Select</a>
<script type="text/javascript">
document.getElementById("someLinkId").onClick =
function() {
SelectSurveyItem('<%itemid%>', '<%itemname%>'); return false;
};
</script>
Então ItemId e itemname precisa ser escapado para JavaScript (isto é, torna-se "
\"
, etc.).
Se você estiver usando Java no lado do servidor, você pode dar uma olhada na classe StringEscapeUtils de common-lang de Jacarta. Caso contrário, não deve demorar muito para escrever seu próprio método 'escapeJavascript'.
É aqui as respostas que você não pode escapar citações usando JavaScript e que você precisa para começar com cordas escaparam.
Por isso. Não há nenhuma maneira de JavaScript ser capaz de lidar com a string 'Marge disse: 'Eu ficaria que era' Peter' e você precisa de seus dados ser limpos antes de oferecê-lo para o script?
Qualquer pena motor bom templates seu sal terá uma função de "citações de fuga". Ours (também home-grown, onde eu trabalho) também tem uma função para escapar citações para javascript. Em ambos os casos, a variável de modelo é, então, apenas anexado com _esc ou _js_esc, dependendo do que você deseja. Você deve conteúdo gerado pelo usuário nunca saída para um navegador que não tenha sido escapou, IMHO.
I enfrentou o mesmo problema, e eu resolver isso de uma maneira complicada. Primeiro faça variáveis ??globais, v1, v2 e v3. E no onclick, envie um indicador, 1, 2 ou 3 e na verificação de função para 1, 2, 3 para colocar o v1, v2 e v3 como:
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);
}