Converter caracteres especiais em HTML em Javascript

121

Alguém sabe como converter caracteres especiais HTMLem Javascript?

Exemplo:

  • &(e comercial) torna-se &amp.
  • "(aspas duplas) torna-se &quotquando ENT_NOQUOTESnão está definido.
  • '(aspas simples) torna-se &#039apenas quando ENT_QUOTESé definido.
  • <(menos que) se torna &lt.
  • >(maior que) se torna &gt.
Jin Yong
fonte
Você pode usar esta biblioteca: npmjs.com/package/utf8
Camilo Ortegón

Respostas:

77

Você precisa de uma função que faça algo como

return mystring.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");

Mas levando em consideração seu desejo de tratamento diferente de aspas simples / duplas.

Steven
fonte
o que a barra g faz?
JohnnyBizzle de
5
@JohnnyBizzle /gem uma expressão regular significa "global". Simplificando, todas as ocorrências da string serão substituídas. Sem /gapenas a primeira partida seria substituída.
Kevin Gimbel
207

A melhor maneira, em minha opinião, é usar a funcionalidade de escape HTML embutida do navegador para lidar com muitos dos casos. Para fazer isso, basta criar um elemento na árvore DOM e definir o innerTextdo elemento para sua string. Em seguida, recupere o innerHTMLdo elemento. O navegador retornará uma string codificada em HTML.

function HtmlEncode(s)
{
  var el = document.createElement("div");
  el.innerText = el.textContent = s;
  s = el.innerHTML;
  return s;
}

Execução de teste:

alert(HtmlEncode('&;\'><"'));

Resultado:

&amp;;'&gt;&lt;"

Este método de escape de HTML também é usado pela biblioteca Prototype JS, embora seja diferente do exemplo simplista que forneci.

Observação: você ainda precisará escapar aspas (duplas e simples). Você pode usar qualquer um dos métodos descritos por outros aqui.

Cerebrus
fonte
3
note que delete elé um erro aqui. perfectionkills.com/understanding-delete
gblazex
Isso não faz nada para mim quando eu tento. Eu recebo os personagens de volta inalterados.
Moss,
1
Desculpe, eu estava testando com caracteres estranhos, além disso, o Chrome é sorrateiro e não mostra a saída HTML real, mas o Firebug mostra (na verdade, ele mostrou uma entidade html para o símbolo de copyright quando a fonte gerada não o codifica). Isso funciona bem, <>&mas não é tão abrangente quanto as soluções da Neotropic ou KooiInc.
Moss,
20
com jQuery,output = $('<div>').text(input).html()
dragon
6
Ambos os métodos não convertem 'em & apos; e "em & quot; Portanto, ainda pode ser usado para ataques XSS.
Alguém
32

Esta função genérica codifica cada caractere não alfabético em seu código html (numérico):

function HTMLEncode(str) {
    var i = str.length,
        aRet = [];

    while (i--) {
        var iC = str[i].charCodeAt();
        if (iC < 65 || iC > 127 || (iC>90 && iC<97)) {
            aRet[i] = '&#'+iC+';';
        } else {
            aRet[i] = str[i];
        }
    }
    return aRet.join('');
}
KooiInc
fonte
Parece muito inteligente, mas só consigo converter o básico:<>&
Moss
nvm. Ele roda bem em um console, mas quando você envia para o navegador, parece que não converteu nada. O que há com isso?
Moss,
@Moss: o navegador renderiza os caracteres codificados em html para os caracteres que eles representam. A vantagem dos caracteres codificados em html é que um navegador não precisa adivinhar a tradução de (por exemplo) caracteres diacríticos e, portanto, sempre renderiza esses caracteres como deveriam ser renderizados.
KooiInc
Você pode considerar alterar isso para remover o acesso do tipo array de str. IE7 e versões anteriores não suportam isso e você pode facilmente chamar charCodeAt diretamente de str com i como o argumento. var iC = str.charCodeAt(i)
Chase
Este código não está produzindo o valor de Entidade HTML correto para o caractere ± que deveria ser & # 177; mas está retornando & # 65533; que é um personagem desconhecido .
Paul,
21

Da Mozilla ...

Observe que charCodeAt sempre retornará um valor menor que 65.536. Isso ocorre porque os pontos de código mais altos são representados por um par de pseudo-caracteres "substitutos" (de valor inferior) que são usados ​​para formar o caractere real. Por causa disso, a fim de examinar ou reproduzir o caractere completo para caracteres individuais de valor 65.536 e acima, para tais caracteres, é necessário recuperar não apenas charCodeAt (i), mas também charCodeAt (i + 1) (como se estivesse examinando / reproduzindo uma string com duas> letras).

A melhor solução

/**
 * (c) 2012 Steven Levithan <http://slevithan.com/>
 * MIT license
 */
if (!String.prototype.codePointAt) {
    String.prototype.codePointAt = function (pos) {
        pos = isNaN(pos) ? 0 : pos;
        var str = String(this),
            code = str.charCodeAt(pos),
            next = str.charCodeAt(pos + 1);
        // If a surrogate pair
        if (0xD800 <= code && code <= 0xDBFF && 0xDC00 <= next && next <= 0xDFFF) {
            return ((code - 0xD800) * 0x400) + (next - 0xDC00) + 0x10000;
        }
        return code;
    };
}

/**
 * Encodes special html characters
 * @param string
 * @return {*}
 */
function html_encode(string) {
    var ret_val = '';
    for (var i = 0; i < string.length; i++) { 
        if (string.codePointAt(i) > 127) {
            ret_val += '&#' + string.codePointAt(i) + ';';
        } else {
            ret_val += string.charAt(i);
        }
    }
    return ret_val;
}

Exemplo de uso:

html_encode("✈");
user1949536
fonte
21

Crie uma função que use string replace

function convert(str)
{
  str = str.replace(/&/g, "&amp;");
  str = str.replace(/>/g, "&gt;");
  str = str.replace(/</g, "&lt;");
  str = str.replace(/"/g, "&quot;");
  str = str.replace(/'/g, "&#039;");
  return str;
}
Matt Hanson
fonte
Eu estava enfrentando problemas com apenas aspas simples (') e aspas duplas (") em meu valor de entrada para exibir em html. O script estava quebrando se o usuário o adicionasse.
Dharam Mali
13

Para aqueles que desejam decodificar um código de caractere inteiro como &#xxx;dentro de uma string, use esta função:

function decodeHtmlCharCodes(str) { 
  return str.replace(/(&#(\d+);)/g, function(match, capture, charCode) {
    return String.fromCharCode(charCode);
  });
}

// Will output "The show that gained int’l reputation’!"
console.log(decodeHtmlCharCodes('The show that gained int&#8217;l reputation&#8217;!'));

ES6

const decodeHtmlCharCodes = str => 
  str.replace(/(&#(\d+);)/g, (match, capture, charCode) => 
    String.fromCharCode(charCode));

// Will output "The show that gained int’l reputation’!"
console.log(decodeHtmlCharCodes('The show that gained int&#8217;l reputation&#8217;!'));

Christos Lytras
fonte
3
Esta deve ser a resposta aceita, pois isso irá decodificar tudo.
Quesofat
Esta é a resposta que eu procurava. Obrigado.
Dzenis H.
8
function char_convert() {

    var chars = ["©","Û","®","ž","Ü","Ÿ","Ý","$","Þ","%","¡","ß","¢","à","£","á","À","¤","â","Á","¥","ã","Â","¦","ä","Ã","§","å","Ä","¨","æ","Å","©","ç","Æ","ª","è","Ç","«","é","È","¬","ê","É","­","ë","Ê","®","ì","Ë","¯","í","Ì","°","î","Í","±","ï","Î","²","ð","Ï","³","ñ","Ð","´","ò","Ñ","µ","ó","Õ","¶","ô","Ö","·","õ","Ø","¸","ö","Ù","¹","÷","Ú","º","ø","Û","»","ù","Ü","@","¼","ú","Ý","½","û","Þ","€","¾","ü","ß","¿","ý","à","‚","À","þ","á","ƒ","Á","ÿ","å","„","Â","æ","…","Ã","ç","†","Ä","è","‡","Å","é","ˆ","Æ","ê","‰","Ç","ë","Š","È","ì","‹","É","í","Œ","Ê","î","Ë","ï","Ž","Ì","ð","Í","ñ","Î","ò","‘","Ï","ó","’","Ð","ô","“","Ñ","õ","”","Ò","ö","•","Ó","ø","–","Ô","ù","—","Õ","ú","˜","Ö","û","™","×","ý","š","Ø","þ","›","Ù","ÿ","œ","Ú"]; 
    var codes = ["&copy;","&#219;","&reg;","&#158;","&#220;","&#159;","&#221;","&#36;","&#222;","&#37;","&#161;","&#223;","&#162;","&#224;","&#163;","&#225;","&Agrave;","&#164;","&#226;","&Aacute;","&#165;","&#227;","&Acirc;","&#166;","&#228;","&Atilde;","&#167;","&#229;","&Auml;","&#168;","&#230;","&Aring;","&#169;","&#231;","&AElig;","&#170;","&#232;","&Ccedil;","&#171;","&#233;","&Egrave;","&#172;","&#234;","&Eacute;","&#173;","&#235;","&Ecirc;","&#174;","&#236;","&Euml;","&#175;","&#237;","&Igrave;","&#176;","&#238;","&Iacute;","&#177;","&#239;","&Icirc;","&#178;","&#240;","&Iuml;","&#179;","&#241;","&ETH;","&#180;","&#242;","&Ntilde;","&#181;","&#243;","&Otilde;","&#182;","&#244;","&Ouml;","&#183;","&#245;","&Oslash;","&#184;","&#246;","&Ugrave;","&#185;","&#247;","&Uacute;","&#186;","&#248;","&Ucirc;","&#187;","&#249;","&Uuml;","&#64;","&#188;","&#250;","&Yacute;","&#189;","&#251;","&THORN;","&#128;","&#190;","&#252","&szlig;","&#191;","&#253;","&agrave;","&#130;","&#192;","&#254;","&aacute;","&#131;","&#193;","&#255;","&aring;","&#132;","&#194;","&aelig;","&#133;","&#195;","&ccedil;","&#134;","&#196;","&egrave;","&#135;","&#197;","&eacute;","&#136;","&#198;","&ecirc;","&#137;","&#199;","&euml;","&#138;","&#200;","&igrave;","&#139;","&#201;","&iacute;","&#140;","&#202;","&icirc;","&#203;","&iuml;","&#142;","&#204;","&eth;","&#205;","&ntilde;","&#206;","&ograve;","&#145;","&#207;","&oacute;","&#146;","&#208;","&ocirc;","&#147;","&#209;","&otilde;","&#148;","&#210;","&ouml;","&#149;","&#211;","&oslash;","&#150;","&#212;","&ugrave;","&#151;","&#213;","&uacute;","&#152;","&#214;","&ucirc;","&#153;","&#215;","&yacute;","&#154;","&#216;","&thorn;","&#155;","&#217;","&yuml;","&#156;","&#218;"];

    for(x=0; x<chars.length; x++){
        for (i=0; i<arguments.length; i++){
            arguments[i].value = arguments[i].value.replace(chars[x], codes[x]);
        }
    }
 }

char_convert(this);
Neotrópico
fonte
1
Isso funciona muito bem., Mas por algum motivo, quando misturado com alguma Funcionalidade JQuery, ele falha. Às vezes converte alguns, ou apenas alguns. Mas, em geral, funciona muito bem. onBlur = "char_convert (este);"
Neotrópico
Uh, recebo um erro "Uncaught TypeError: não é possível chamar o método 'replace' of undefined" no Chrome e "arguments [i] .value is undefined" no Firebug.
Moss,
colocar todos esses caracteres especiais em uma matriz como essa é completamente inútil. veja outras respostas.
Gavin de
Melhor solução para mim, a única que converte í para & iacute; por exemplo.
Edhowler
Como você obtém esses caracteres do seu teclado? Eu sei que esta é uma pergunta boba ... no OS X por exemplo
PositiveGuy
7

Como foi mencionado, dragona maneira mais limpa de fazer isso é com jQuery:

function HtmlEncode(s) {
    return $('<div>').text(s).html();
}

function HtmlDecode(s) {
    return $('<div>').html(s).text();
}
Serj Sagan
fonte
Interessante, mas se sua string contiver um espaço, isso não o alterará. A melhor maneira é usar encodeURI (yourString);
Mike Gledhill
6
function ConvChar (str) {
  c = {'<': '& lt;', '>': '& gt;', '&': '& amp;', '"': '& quot;'," '":' & # 039; ',
       '#': '& # 035;' };
  return str.replace (/ [<&> '"#] / g, função (ões) {return c [s];});
}

alert (ConvChar ('<- "- & -" -> - <- \' - # - \ '->'));

Resultado:

& lt; - & quot; - & amp; - & quot; - & gt; - & lt; - & # 039; - & # 035; - & # 039; - & gt;

In testarea tag:

<- "- & -" -> - <-'- # -'->

Se você apenas mudar alguns caracteres no código longo ...

user262419
fonte
4

Em uma PREtag - e na maioria das outras tags HTML - texto simples para um arquivo em lote que usa os caracteres de redirecionamento de saída (<e>) quebrará o HTML, mas aqui está minha dica : vale tudo em um TEXTAREAelemento - não quebrará o HTML, principalmente porque estamos dentro de um controle instanciado e manipulado pelo SO, e portanto seu conteúdo não está sendo analisado pelo motor HTML.

Como exemplo, digamos que eu queira destacar a sintaxe do meu arquivo em lote usando javascript. Simplesmente colo o código em uma textarea sem me preocupar com os caracteres reservados do HTML, e faço o script processar a innerHTMLpropriedade da textarea, que avalia o texto com os caracteres reservados do HTML substituídos por suas entidades ISO-8859-1 correspondentes.

Os navegadores escaparão de caracteres especiais automaticamente quando você recuperar a propriedade innerHTML(e outerHTML) de um elemento. Usar uma textarea (e quem sabe, talvez uma entrada do tipo text) apenas evita que você faça a conversão (manualmente ou por meio de código).

Eu uso esse truque para testar meu realce de sintaxe e, quando termino a criação e o teste, simplesmente oculto a área de texto da visualização.

Hector-J-Rivas
fonte
3

uma solução alternativa:

var temp = $("div").text("<");
var afterEscape = temp.html(); // afterEscape == "&lt;"
Keshin
fonte
2
var swapCodes   = new Array(8211, 8212, 8216, 8217, 8220, 8221, 8226, 8230, 8482, 169, 61558, 8226, 61607);
var swapStrings = new Array("--", "--", "'",  "'",  '"',  '"',  "*",  "...", "&trade;", "&copy;", "&bull;", "&bull;", "&bull;");

var TextCheck = {
    doCWBind:function(div){
        $(div).bind({
            bind:function(){
                TextCheck.cleanWord(div);
            },
            focus:function(){
                TextCheck.cleanWord(div);
            },
            paste:function(){
                TextCheck.cleanWord(div);
            }
        }); 
    },
    cleanWord:function(div){
        var output = $(div).val();
        for (i = 0; i < swapCodes.length; i++) {
            var swapper = new RegExp("\\u" + swapCodes[i].toString(16), "g");
            output = output.replace(swapper, swapStrings[i]);
        }
        $(div).val(output);
    }
}

Outro que usamos agora que funciona. Um acima, chamei um script em vez disso e retorna o código convertido. Só é bom em áreas de texto pequenas (o que significa que não é um artigo completo / ect de blog ...)


Para cima. Funciona na maioria dos chars.

var swapCodes   = new Array(8211, 8212, 8216, 8217, 8220, 8221, 8226, 8230, 8482, 61558, 8226, 61607,161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 338, 339, 352, 353, 376, 402);
var swapStrings = new Array("--", "--", "'",  "'",  '"',  '"',  "*",  "...", "&trade;", "&bull;", "&bull;", "&bull;", "&iexcl;", "&cent;", "&pound;", "&curren;", "&yen;", "&brvbar;", "&sect;", "&uml;", "&copy;", "&ordf;", "&laquo;", "&not;", "&shy;", "&reg;", "&macr;", "&deg;", "&plusmn;", "&sup2;", "&sup3;", "&acute;", "&micro;", "&para;", "&middot;", "&cedil;", "&sup1;", "&ordm;", "&raquo;", "&frac14;", "&frac12;", "&frac34;", "&iquest;", "&Agrave;", "&Aacute;", "&Acirc;", "&Atilde;", "&Auml;", "&Aring;", "&AElig;", "&Ccedil;", "&Egrave;", "&Eacute;", "&Ecirc;", "&Euml;", "&Igrave;", "&Iacute;", "&Icirc;", "&Iuml;", "&ETH;", "&Ntilde;", "&Ograve;", "&Oacute;", "&Ocirc;", "&Otilde;", "&Ouml;", "&times;", "&Oslash;", "&Ugrave;", "&Uacute;", "&Ucirc;", "&Uuml;", "&Yacute;", "&THORN;", "&szlig;", "&agrave;", "&aacute;", "&acirc;", "&atilde;", "&auml;", "&aring;", "&aelig;", "&ccedil;", "&egrave;", "&eacute;", "&ecirc;", "&euml;", "&igrave;", "&iacute;", "&icirc;", "&iuml;", "&eth;", "&ntilde;", "&ograve;", "&oacute;", "&ocirc;", "&otilde;", "&ouml;", "&divide;", "&oslash;", "&ugrave;", "&uacute;", "&ucirc;", "&uuml;", "&yacute;", "&thorn;", "&yuml;", "&#338;", "&#339;", "&#352;", "&#353;", "&#376;", "&#402;");

Eu crio um arquivo javascript que tem muitas funcionalidades, incluindo as acima. http://www.neotropicsolutions.com/JSChars.zip

Todos os arquivos necessários estão incluídos. Eu adicionei o jQuery 1.4.4. Simplesmente porque vi problemas em outras versões, ainda não as experimentei.

Requires: jQuery & jQuery Impromptu from: http://trentrichardson.com/Impromptu/index.php

1. Word Count
2. Character Conversion
3. Checks to ensure this is not passed: "notsomeverylongstringmissingspaces"
4. Checks to make sure ALL IS NOT ALL UPPERCASE.
5. Strip HTML

    // Word Counter
    $.getScript('js/characters.js',function(){
            $('#adtxt').bind("keyup click blur focus change paste",
                function(event){
                    TextCheck.wordCount(30, "#adtxt", "#adtxt_count", event);
            });
            $('#adtxt').blur(
                function(event){
                    TextCheck.check_length('#adtxt'); // unsures properly spaces-not one long word
                    TextCheck.doCWBind('#adtxt');// char conversion
            });

            TextCheck.wordCount(30, "#adtxt", "#adtxt_count", false);
        });

    //HTML
    <textarea name="adtxt" id="adtxt" rows="10" cols="70" class="wordCount"></textarea>
<div id="adtxt_count" class="clear"></div>

    // Just Character Conversions:
    TextCheck.doCWBind('#myfield');

    // Run through form fields in a form for case checking.
    // Alerts user when field is blur'd.
    var labels = new Array("Brief Description","Website URL","Contact Name","Website","Email","Linkback URL");
    var checking = new Array("descr","title","fname","website","email","linkback");
    TextCheck.check_it(checking,labels);

    // Extra security to check again, make sure form is not submitted
    var pass = TextCheck.validate(checking,labels);
    if(pass){
        //do form actions
    }


    //Strip HTML
    <textarea name="adtxt" id="adtxt" rows="10" cols="70" onblur="TextCheck.stripHTML(this);"></textarea>
Neotrópico
fonte
2
 <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>html</title>  
      <script>
      $(function() {   
      document.getElementById('test').innerHTML = "&amp;";
      });

      </script>
    </head>
    <body>
    <div id="test"></div>
    </body>
    </html>

você pode simplesmente converter caracteres especiais em html usando o código acima.

Sanman
fonte
2

Aqui está uma boa biblioteca que achei muito útil neste contexto.

https://github.com/mathiasbynens/he

Segundo seu autor:

Ele suporta todas as referências de caracteres nomeados padronizados como por HTML, lida com ampersands ambíguos e outros casos extremos como um navegador faria, tem um amplo conjunto de testes e - ao contrário de muitas outras soluções JavaScript - ele lida perfeitamente com símbolos Unicode astrais

Dipesh KC
fonte
Esta ferramenta github.com/mathiasbynens/he para matemática é muito boa e tem playground online também
Mohamed Hussain
1

Aqui estão alguns métodos que uso sem a necessidade de Jquery:

Você pode codificar cada caractere em sua string:

function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}

Ou apenas direcione os principais caracteres de codificação segura para se preocupar (&, inebreaks, <,>, "e ') como:

function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}

test.value=encode('How to encode\nonly html tags &<>\'" nice & fast!');

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55">www.WHAK.com</textarea>

Dave Brown
fonte
0
function escape (text)
{
  return text.replace(/[<>\&\"\']/g, function(c) {
    return '&#' + c.charCodeAt(0) + ';';
  });
}

alert(escape("<>&'\""));
Chris
fonte
0

Isso não responde diretamente à sua pergunta, mas se você estiver usando innerHTMLpara escrever texto dentro de um elemento e tiver problemas de codificação, apenas use textContent, ou seja:

var s = "Foo 'bar' baz <qux>";

var element = document.getElementById('foo');
element.textContent = s;

// <div id="foo">Foo 'bar' baz <qux></div>
Simone
fonte
0

Podemos usar javascript DOMParserpara conversão de caracteres especiais.

const parser = new DOMParser();
const convertedValue = (parser.parseFromString("&#039 &amp &#039 &lt &gt", "application/xml").body.innerText;
Ankit Arya
fonte
0

A seguir está a função simples para codificar caracteres de escape xml em JS

Encoder.htmlEncode (unsafeText);

user1211004
fonte
0

Você pode corrigi-lo substituindo a função .text () por .html (). está funcionando para mim.

user3040433
fonte
-1
<html>
<body>
<script type="text/javascript">
var str= "&\"'<>";
alert('B4 Change:\n' + str);
str= str.replace(/\&/g,'&amp;');
str= str.replace(/</g,'&lt;');
str= str.replace(/>/g,'&gt;');
str= str.replace(/\"/g,'&quot;');
str= str.replace(/\'/g,'&#039;');
alert('After change:\n' + str);
</script>
</body>
</html>      

use isso para testar: http://www.w3schools.com/js/tryit.asp?filename=tryjs_text


fonte
-1

Sim, mas se você precisar inserir a string resultante em algum lugar sem que seja convertida de volta, você precisa fazer:

str.replace(/'/g,"&amp;amp;#39;"); // and so on
Graham
fonte
-4

Use a função javaScript escape () , que permite codificar strings.

por exemplo,

escape("yourString");
Benaiah
fonte
1
Codifique para inserir uma URL não para HTML (e a função está obsoleta de qualquer maneira, pois é quebrada para Unicode).
Quentin
-4
public static string HtmlEncode (string text)
{
    string result;
    using (StringWriter sw = new StringWriter())
    {
        var x = new HtmlTextWriter(sw);
        x.WriteEncodedText(text);
        result = sw.ToString();
    }
    return result;

}
Shahyad Sharghi
fonte
Essa solução é mesmo um código javascript? Porque parece JAVA ou C # para mim.
Mr.TK
Isso não é Javascript.
Diego Fortes