Convertir caracteres especiales a HTML en Javascript

121

¿Alguien sabe cómo convertir caracteres especiales HTMLen Javascriptpulgadas?

Ejemplo:

  • &(ampersand) se convierte en &amp.
  • "(comillas dobles) se convierte en &quotcuando ENT_NOQUOTESno se establece.
  • '(comillas simples) pasa a ser &#039solo cuando ENT_QUOTESse establece.
  • <(menos que) se convierte en &lt.
  • >(mayor que) se convierte en &gt.
Jin Yong
fuente
Puede utilizar esta biblioteca: npmjs.com/package/utf8
Camilo Ortegón

Respuestas:

77

Necesitas una función que haga algo como

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

Pero teniendo en cuenta su deseo de un manejo diferente de comillas simples / dobles.

Steven
fuente
¿Qué hace la barra inclinada g?
JohnnyBizzle
5
@JohnnyBizzle /gen una expresión regular significa "global". En pocas palabras, se reemplazarán todas las apariciones de la cadena. Sin /gsolo el primer partido sería reemplazado.
Kevin Gimbel
207

En mi opinión, la mejor manera es utilizar la funcionalidad de escape HTML incorporada en el navegador para manejar muchos de los casos. Para hacer esto, simplemente cree un elemento en el árbol DOM y establezca el innerTextdel elemento en su cadena. Luego recupere el innerHTMLdel elemento. El navegador devolverá una cadena codificada en HTML.

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

Prueba de funcionamiento:

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

Salida:

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

Este método de escape HTML también es utilizado por la biblioteca Prototype JS. aunque de manera diferente a la muestra simplista que he dado.

Nota: Aún necesitará escapar de las comillas (dobles y simples) usted mismo. Puede utilizar cualquiera de los métodos descritos por otros aquí.

Cerebrus
fuente
3
tenga en cuenta que delete eles un error aquí. perfectionkills.com/understanding-delete
gblazex
Esto no me hace nada cuando lo intento. Recuperé los personajes sin cambios.
Moss
1
Lo siento, estaba probando con caracteres extraños, además de que Chrome es astuto y no muestra la salida HTML real, pero Firebug sí (en realidad mostró una entidad html para el símbolo de derechos de autor cuando la fuente generada no lo codifica). Esto funciona bien, <>&pero no es tan completo como las soluciones de Neotropic o KooiInc.
Moss
20
con jQuery,output = $('<div>').text(input).html()
dragón
6
Ambos métodos no convierten 'en & apos; y "en" Por lo que todavía se puede utilizar para ataques XSS.
Alguien
32

Esta función genérica codifica cada carácter no alfabético en su 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
fuente
Esto suena realmente inteligente, pero solo puedo convertir lo básico:<>&
Moss
nvm. Se ejecuta bien en una consola, pero cuando se envía al navegador parece que no ha convertido cosas. ¿Qué pasa con eso?
Moss
@Moss: el navegador convierte los caracteres codificados en htmlen a los caracteres que representan. La ventaja de los caracteres codificados en html es que un navegador no tiene que adivinar la traducción de (por ejemplo) caracteres diacríticos y, por lo tanto, siempre muestra esos caracteres como deberían.
KooiInc
Podría considerar cambiar esto para eliminar el acceso similar a una matriz de str. IE7 y versiones anteriores no admiten eso, y puede llamar fácilmente a charCodeAt directamente desde str con i como argumento. var iC = str.charCodeAt(i)
persecución
Este código no produce el valor de entidad HTML correcto para el carácter ±, que debería ser & # 177; pero está regresando & # 65533; que es un carácter desconocido .
Paul
21

Desde Mozilla ...

Tenga en cuenta que charCodeAt siempre devolverá un valor menor que 65.536. Esto se debe a que los puntos de código más altos están representados por un par de pseudocaracteres "sustitutos" (de menor valor) que se utilizan para comprender el carácter real. Debido a esto, para examinar o reproducir el carácter completo para caracteres individuales de valor 65,536 y superior, para dichos caracteres, es necesario recuperar no solo charCodeAt (i), sino también charCodeAt (i + 1) (como si examinara / reproduciendo una cadena con dos> letras).

La mejor solucion

/**
 * (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;
}

Ejemplo de uso:

html_encode("✈");
user1949536
fuente
21

Crea una función que use cadena 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
fuente
Estaba enfrentando un problema con solo comillas simples (') y comillas dobles (") en mi valor de entrada para mostrar en html. El script se rompía si el usuario lo agregaba.
Dharam Mali
13

Para aquellos que quieran decodificar un código de caracteres enteros como &#xxx;dentro de una cadena, use esta función:

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
fuente
3
Esta debería ser la respuesta aceptada ya que decodificará todo.
Quesofat
Esta es la respuesta que estaba buscando. Gracias.
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
fuente
1
Esto funciona muy bien. Pero por alguna razón cuando se mezcla con alguna funcionalidad de JQuery, falla. A veces lo convierte en algunos, o solo en un par. Pero en general, funciona muy bien. onBlur = "char_convert (esto);"
Neotrópico
Uh, recibo un error "Uncaught TypeError: No se puede llamar al método 'replace' de undefined" en Chrome y "los argumentos [i] .value is undefined" en Firebug.
Moss
poner todos esos caracteres especiales en una matriz como esa es completamente inútil. ver otras respuestas.
Gavin
La mejor solución para mí, la única que convierte í en & iacute; por ejemplo.
Edhowler
¿Cómo obtienes esos caracteres de tu teclado? Sé que esta es una pregunta tonta ... en OS X, por ejemplo
PositiveGuy
7

Como se mencionó, dragonla forma más limpia de hacerlo es con jQuery:

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

function HtmlDecode(s) {
    return $('<div>').html(s).text();
}
Serj Sagan
fuente
Interesante, pero si su cadena contiene un espacio, esto no lo alterará. Una mejor forma es utilizar encodeURI (yourString);
Mike Gledhill
6
function ConvChar (str) {
  c = {'<': '& lt;', '>': '& gt;', '&': '& amp;', '"': '& quot;'," '":' & # 039; ',
       '#': '& # 035;' };
  return str.replace (/ [<&> '"#] / g, función (es) {return c [s];});
}

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

Resultado:

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

En la etiqueta testarea:

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

Si solo cambia un poco de caracteres en código largo ...

usuario262419
fuente
4

En una PREetiqueta, y en la mayoría de las otras etiquetas HTML, el texto sin formato de un archivo por lotes que usa los caracteres de redirección de salida (<y>) romperá el HTML, pero aquí está mi consejo : todo vale en un TEXTAREAelemento, no romperá el HTML, principalmente porque estamos dentro de un control instanciado y manejado por el sistema operativo, y por lo tanto su contenido no está siendo analizado por el motor HTML.

Como ejemplo, digamos que quiero resaltar la sintaxis de mi archivo por lotes usando javascript. Simplemente pego el código en un área de texto sin preocuparme por los caracteres reservados HTML, y hago que el script procese la innerHTMLpropiedad del área de texto, que evalúa el texto con los caracteres reservados HTML reemplazados por sus entidades ISO-8859-1 correspondientes.

Los navegadores escaparán de los caracteres especiales automáticamente cuando recupere la propiedad innerHTML(y outerHTML) de un elemento. El uso de un área de texto (y quién sabe, tal vez una entrada de tipo texto) simplemente le evita hacer la conversión (manualmente o mediante código).

Utilizo este truco para probar mi resaltador de sintaxis, y cuando termino de crear y probar, simplemente oculto el área de texto de la vista.

hector-j-rivas
fuente
3

una solución alternativa:

var temp = $("div").text("<");
var afterEscape = temp.html(); // afterEscape == "&lt;"
keshin
fuente
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);
    }
}

Otro que usamos ahora que funciona. Uno de arriba lo tengo llamando a un script y devuelve el código convertido. Solo es bueno en áreas de texto pequeñas (es decir, no es un artículo completo / blog, etc.)


Por arriba. Funciona en la mayoría de los caracteres.

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;");

Creo un archivo javascript que tiene muchas funciones, incluidas las anteriores. http://www.neotropicsolutions.com/JSChars.zip

Se incluyen todos los archivos necesarios. Agregué jQuery 1.4.4. Simplemente porque vi problemas en otras versiones, pero aún no los he probado.

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
fuente
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>

simplemente puede convertir caracteres especiales a html usando el código anterior.

sanman
fuente
2

Aquí hay una buena biblioteca que he encontrado muy útil en este contexto.

https://github.com/mathiasbynens/he

Según su autor:

Admite todas las referencias de caracteres con nombre estandarizadas según HTML, maneja símbolos de unión ambiguos y otros casos extremos como lo haría un navegador, tiene un amplio conjunto de pruebas y, al contrario de muchas otras soluciones de JavaScript, maneja bien los símbolos Unicode astrales

Dipesh KC
fuente
Esta herramienta github.com/mathiasbynens/he para Mathias es muy buena y también tiene un área de juegos en línea
Mohamed Hussain
1

Aquí hay un par de métodos que uso sin la necesidad de Jquery:

Puede codificar todos los caracteres de su cadena:

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

O simplemente apunte a los principales caracteres de codificación segura de los que preocuparse (&, inebreaks, <,> "y ') 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
fuente
0
function escape (text)
{
  return text.replace(/[<>\&\"\']/g, function(c) {
    return '&#' + c.charCodeAt(0) + ';';
  });
}

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

Esto no responde directamente a su pregunta, pero si está utilizando innerHTMLpara escribir texto dentro de un elemento y se encontró con problemas de codificación, simplemente use textContent, es decir:

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

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

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

Podemos usar javascript DOMParserpara la conversión de caracteres especiales.

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

A continuación se muestra la función simple para codificar caracteres de escape xml en JS

Encoder.htmlEncode (unsafeText);

usuario1211004
fuente
0

Puede solucionarlo reemplazando la función .text () por .html (). está trabajando para mí.

usuario3040433
fuente
-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 esto para probar: http://www.w3schools.com/js/tryit.asp?filename=tryjs_text


fuente
-1

Sí, pero si necesita insertar la cadena resultante en algún lugar sin que se vuelva a convertir, debe hacer:

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

Utilice la función de javaScript escape () , que le permite codificar cadenas.

p.ej,

escape("yourString");
Benaía
fuente
1
Codifique para introducir una URL que no sea para HTML (y la función está obsoleta de todos modos ya que no funciona con 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
fuente
¿Es esta solución incluso un código javascript? Porque me parece JAVA o C #.
Mr.TK
Esto no es Javascript.
Diego Fortes