Citações de escape em JavaScript

211

Estou produzindo valores de um banco de dados (não é realmente aberto à entrada pública, mas é aberto à entrada por um usuário na empresa - ou seja, não estou preocupado com o XSS ).

Estou tentando gerar uma tag como esta:

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

DESCRIPTION é realmente um valor do banco de dados que é algo como isto:

Prelim Assess "Mini" Report

Eu tentei substituir "por", mas não importa o que eu tente, o Firefox continua cortando minha chamada de JavaScript após o espaço após a palavra Avaliação , e está causando todos os tipos de problemas.

Devo confundir a resposta óbvia, mas pela minha vida não consigo descobrir.

Alguém quer apontar minha idiotice?

Aqui está toda a página HTML (será uma página ASP.NET eventualmente, mas, para resolver isso, retirei todo o resto, exceto o código do problema)

<html>
    <body>
        <a href="#" onclick="DoEdit('Preliminary Assessment \"Mini\"'); return false;">edit</a>
    </body>
</html>
Matt Dawdy
fonte
3
É uma boa idéia tornar o onclickanexo do seu evento discreto e mover todas as informações do banco de dados para um console de dados. As coisas ficarão mais limpas e você realmente receberá algum tipo de erro de sintaxe quando suas seqüências de caracteres forem escapadas incorretamente.
Justin Johnson
Você também pode usar escape ( "string") e unescape ( "string") métodos do jQuery
Abhiram

Respostas:

212

Você precisa escapar da string em que está escrevendo para DoEditeliminar os caracteres de aspas duplas. Eles estão fazendo com que o onclickatributo HTML seja fechado prematuramente.

O uso do caractere de escape JavaScript,, \não é suficiente no contexto HTML. Você precisa substituir as aspas duplas pela representação apropriada da entidade XML &quot;,.

Aaron
fonte
Certo, mas não seria isso? <a href="#" onclick="DoEdit('Avaliação preliminar \"Mini\"'); return false;"> editar </a> Eu tentei isso e ainda está estragando tudo. Isso tem que ser um WTF simples, mas para a minha vida, eu não consigo vê-lo.
Matt Dawdy
Existe alguma função JavaScript interna que possa escapar das aspas duplas? Além de 'quo "'. Replace ('"', '& quot;'), não consigo encontrar nada.
kevin
4
Não é um problema de javascript, é um problema de codificação HTML / XML: você não pode ter aspas duplas dentro de um valor de atributos sem escapá-los ... caso contrário, os navegadores / analisadores acham que está terminando a declaração do valor do atributo.
Aaron
22
código de substituição de exemplo:'mystring'.replace(/"/g, '&quot;');
Joshua Burns
3
no comentário anterior, há uma citação extra. O código que funciona é 'mystring'.replace (/' / g, '& quot;');
Agustin Lopez
95

&quot; funcionaria nesse caso específico, como sugerido antes de mim, por causa do contexto HTML.

No entanto, se você deseja que seu código JavaScript seja escapado independentemente para qualquer contexto, você pode optar pela codificação JavaScript nativa:
'torna- \x27
"se\x22

Assim, o seu onclick se tornaria:
DoEdit('Preliminary Assessment \x22Mini\x22');

Isso funcionaria, por exemplo, também ao passar uma string JavaScript como parâmetro para outro método JavaScript ( alert()é um método de teste fácil para isso).

Estou lhe referindo à pergunta duplicada Stack Overflow: Como escapar uma string dentro do código JavaScript dentro de um manipulador onClick? .

tsemer
fonte
2
Obrigado! A sua é a resposta mais correta, pois é JavaScript nativo, independentemente do contexto.
scarver2
2
Esta é a resposta correta, embora em um contexto HTML o uso &quot;, obviamente, funcione.
1113 Oliver
Observe que &quot;é necessário nos valores de entrada, ou seja, <input value="\x22quoted string\x22">não funcionará.
thdoan
@ 10basetom naturalmente, o escape de JavaScript só funciona em um contexto JavaScript, como manipuladores de eventos ( onclick="..."). O valor de um valueatributo não está sendo processado em um contexto JavaScript, apenas em um contexto HTML.
tsemer
código de substituição:'mystring'.replace(/"/g, '\\x22').replace(/'/g, '\\x27')
galinhas
33
<html>
    <body>
        <a href="#" onclick="DoEdit('Preliminary Assessment &quot;Mini&quot;'); return false;">edit</a>
    </body>
</html>

Deve fazer o truque.

kristian
fonte
24

Pessoal, já existe a unescapefunção em JavaScript que faz o escape para \":

<script type="text/javascript">
    var str="this is \"good\"";
    document.write(unescape(str))
</script>
rohtakdev
fonte
2
Uma combinação de "escape" / "unescape" fez o que eu precisava. Obrigado.
Luis R.
8
escape / unescape estão obsoletos. embora o encodeURI faça mais do que apenas aspas. gotochriswest.com/blog/2011/05/23/escape-unescape-deprecated
chug2k
12

O problema é que o HTML não reconhece o caractere de escape. Você pode contornar isso usando aspas simples para o atributo HTML e aspas duplas para o onclick.

<a href="#" onclick='DoEdit("Preliminary Assessment \"Mini\""); return false;'>edit</a>
dl.
fonte
5
Caramba. Fiquei me perguntando por que naturalmente eu recorri ao 'para o atributo no passado. Eu nunca mergulhei nisso tudo tão profundamente. Obrigado.
Matt Dawdy
6

É assim que eu faço, basicamente 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>

Ronnie Royston
fonte
2

Se você estiver montando o HTML em Java, poderá usar esta boa classe de utilitário do Apache commons-lang para fazer todo o escape corretamente:

org.apache.commons.lang.StringEscapeUtils
Escapa e desmarca seqüências de caracteres para Java, Java Script, HTML, XML e SQL.

eu pego
fonte
Eu uso org.apache.commons.lang3.StringEscapeUtils.escapeEcmaScript (texto) para construir methodExpression em Java. Obrigado.
Harun
1

Eu fiz uma amostra usando jQuery

var descr = 'test"inside"outside';
$(function(){
   $("#div1").append('<a href="#" onclick="DoEdit(descr);">Click Me</a>');       
});

function DoEdit(desc)
{
    alert ( desc );
}

E isso funciona no Internet Explorer e Firefox.

rahul
fonte
5
Claro que sim, porque você não está colocando diretamente no atributo Para usar seu método, eu teria que criar uma matriz de strings JS e, em seguida, executar um número arbitrário de atribuições $ ("# divxxx") .... Menos que o ideal, mas obrigado pela sugestão.
Matt Dawdy
1

Você pode copiar essas duas funções (listadas abaixo) e usá-las para escapar / remover todas as aspas e caracteres especiais. Você não precisa usar o jQuery ou qualquer outra biblioteca para isso.

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, '\\');
}
omanosoft
fonte
1

Por favor, encontre o código abaixo que escapa as aspas simples como parte da string inserida usando uma expressão regular. Ele valida se a sequência inserida pelo usuário é separada por vírgulas e, ao mesmo tempo, escapa até as aspas simples inseridas como parte da sequência.

Para escapar de aspas simples, basta inserir uma barra invertida seguida por uma aspas simples como: \ ' como parte da sequência. Eu usei o validador jQuery para este exemplo, e você pode usar conforme sua conveniência.

Exemplos de strings válidos:

'Olá'

'Olá Mundo'

'Olá Mundo'

'Olá Mundo',' '

'É o meu mundo', 'Não é possível aproveitar isso sem mim.', 'Bem-vindo, Visitante'

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.');
Dinesh Lomte
fonte
0

Fuja do espaço em branco também. Parece-me que o Firefox está assumindo três argumentos em vez de um. &nbsp;é o caractere de espaço sem quebra. Mesmo que não seja o problema, ainda pode ser uma boa ideia.

o Hampster
fonte
0

Você precisa escapar de aspas com barras invertidas duplas.

Isso falha (produzido pelo json_encode do PHP ):

<script>
  var jsonString = '[{"key":"my \"value\" "}]';
  var parsedJson = JSON.parse(jsonString);
</script>

Isso funciona:

<script>
  var jsonString = '[{"key":"my \\"value\\" "}]';
  var parsedJson = JSON.parse(jsonString);
</script>
Búfalo
fonte
0

Você pode usar os métodos jQuery escape () e unescape (). Como abaixo,

Use escape(str);para escapar da string e recuperar novamente usando unescape(str_esc);.

Abhiram
fonte