用 JavaScript 编码 HTML 实体

我工作在一个 CMS,允许用户输入内容。问题是,当他们添加符号 ®,它可能不会在所有浏览器显示良好。我想设置一个必须搜索的符号列表,然后转换为相应的 html 实体。比如说

= > ®
& = > &
= > ©
TM = > &trade; < br >

转换之后,需要将其包装在 <sup>标记中,结果是:

® = > <sup>&reg;</sup>

因为特定的字体大小和填充样式是必要的:

sup { font-size: 0.6em; padding-top: 0.2em; }

JavaScript 会是这样的东西吗?

var regs = document.querySelectorAll('®');
for ( var i = 0, l = imgs.length; i < l; ++i ) {
var [?] = regs[i];
var [?] = document.createElement('sup');
img.parentNode.insertBefore([?]);
div.appendChild([?]);
}

“[ ? ]”意思是有些事情我不确定。

更多详情:

  • 我希望使用纯 JavaScript 来完成这项工作,而不是使用 需要像 jQuery 这样的库,谢谢。
  • 后端是 Ruby
  • 使用用 RubyonRails 构建的 RefereryCMS
351342 次浏览

您可以使用正则表达式将给定 unicode 范围内的任何字符替换为与其对应的 html 实体。代码如下所示:

var encodedStr = rawStr.replace(/[\u00A0-\u9999<>\&]/g, function(i) {
return '&#'+i.charCodeAt(0)+';';
});

这段代码将用它们的 html 实体等价物替换给定范围内的所有字符(unicode 00A0-9999,以及 & 符号,大于 & 小于) ,这个实体等价物就是简单的 &#nnn;,其中 nnn是我们从 charCodeAt获得的 unicode 值。

在这里可以看到它的作用: http://jsfiddle.net/E3EqX/13/(这个示例对示例中使用的元素选择器使用 jQuery。上面的基本代码本身不使用 jQuery)

进行这些转换并不能解决所有问题——确保使用的是 UTF8字符编码,确保数据库将字符串存储在 UTF8中。根据系统字体配置和其他超出您控制范围的问题,还是可能会看到字符显示不正确的实例。

文件

您可以使用 charCodeAt()方法检查指定字符的值是否大于127,然后使用 toString(16)将其转换为字符值引用。

目前公认的答案 有几个问题。这篇文章解释了它们,并提供了一个更健壮的解决方案。该答复中提出的解决办法是:

var encodedStr = rawStr.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#' + i.charCodeAt(0) + ';';
});

i标志是多余的,因为从 U + 00 A0到 U + 9999的范围内没有 Unicode 符号的大小写变体超出了相同的范围。

m标志是多余的,因为正则表达式中没有使用 ^$

为什么 U + 00 A0到 U + 9999的范围这么大? 看起来有点武断。

无论如何,对于一个解决方案,正确编码 所有除了安全和可打印的 ASCII 符号在输入(包括星体符号!),并实现所有命名的字符引用(不仅仅是 HTML4中的引用) ,使用(免责声明: 此库是我的)。自述:

He (用于“ HTML 实体”)是一个用 JavaScript 编写的健壮的 HTML 实体编码器/解码器。它支持 所有标准化的命名字符引用,处理 不明确的 & 符号和其他边缘情况 就像浏览器一样,有一个广泛的测试套件,而且ーー与许多其他 JavaScript 解决方案不同的是ーー 可以很好地处理星形 Unicode 符号。一个在线演示是可用的。

也请参阅 这个相关的堆栈溢出答案

我也遇到过同样的问题,我创建了两个函数来创建实体并将它们转换回普通字符。 以下方法将任何字符串转换为 HTML 实体并返回到 String 原型

/**
* Convert a string to HTML entities
*/
String.prototype.toHtmlEntities = function() {
return this.replace(/./gm, function(s) {
// return "&#" + s.charCodeAt(0) + ";";
return (s.match(/[a-z0-9\s]+/i)) ? s : "&#" + s.charCodeAt(0) + ";";
});
};


/**
* Create string from HTML entities
*/
String.fromHtmlEntities = function(string) {
return (string+"").replace(/&#\d+;/gm,function(s) {
return String.fromCharCode(s.match(/\d+/gm)[0]);
})
};

然后,您可以按以下方式使用它:

var str = "Test´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æøπ£¨ ƒ™en tést".toHtmlEntities();
console.log("Entities:", str);
console.log("String:", String.fromHtmlEntities(str));

控制台输出:

Entities: &#68;&#105;&#116;&#32;&#105;&#115;&#32;&#101;&#180;&#8224;&#174;&#165;&#168;&#169;&#729;&#8747;&#248;&#8230;&#710;&#402;&#8710;&#247;&#8721;&#8482;&#402;&#8710;&#230;&#248;&#960;&#163;&#168;&#160;&#402;&#8482;&#101;&#110;&#32;&#116;&#163;&#101;&#233;&#115;&#116;
String: Dit is e´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æøπ£¨ ƒ™en t£eést

如果您已经在使用 jQuery,请尝试使用 html()

$('<div>').text('<script>alert("gotcha!")</script>').html()
// "&lt;script&gt;alert("gotcha!")&lt;/script&gt;"

内存中的文本节点被实例化,并在其上调用 html()

它很难看,浪费了一点内存,我不知道它是否像 he库那样全面,但是如果您已经在使用 jQuery,也许这是一个适合您的选项。

摘自 Felix Geisendörfer 的博客文章 用 jQuery 编码 HTML 实体

对于那些在谷歌上搜索如何编码 html 实体的人来说,这是一个答案,因为它并没有真正解决关于 < sup > 包装器和符号实体的问题。

对于 HTML 标记实体(& 、 < 和 >) ,不需要任何库,如果不需要支持 IE < 9,可以创建一个 HTML 元素并用 TextContent设置其内容:

var str = "<this is not a tag>";
var p = document.createElement("p");
p.textContent = str;
var converted = p.innerHTML;

这里有一个例子: https://jsfiddle.net/1erdhehv/

有时候你只是想编码每个字符... 这个函数代替了 regxp 中的“ everything but nothing”。

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

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


test.value=encode(document.body.innerHTML.trim());
<textarea id=test rows=11 cols=55>www.WHAK.com</textarea>

你可以用这个。

var escapeChars = {
'¢' : 'cent',
'£' : 'pound',
'¥' : 'yen',
'€': 'euro',
'©' :'copy',
'®' : 'reg',
'<' : 'lt',
'>' : 'gt',
'"' : 'quot',
'&' : 'amp',
'\'' : '#39'
};


var regexString = '[';
for(var key in escapeChars) {
regexString += key;
}
regexString += ']';


var regex = new RegExp( regexString, 'g');


function escapeHTML(str) {
return str.replace(regex, function(m) {
return '&' + escapeChars[m] + ';';
});
};

Https://github.com/epeli/underscore.string/blob/master/escapehtml.js

var htmlEntities = {
nbsp: ' ',
cent: '¢',
pound: '£',
yen: '¥',
euro: '€',
copy: '©',
reg: '®',
lt: '<',
gt: '>',
quot: '"',
amp: '&',
apos: '\''
};


function unescapeHTML(str) {
return str.replace(/\&([^;]+);/g, function (entity, entityCode) {
var match;


if (entityCode in htmlEntities) {
return htmlEntities[entityCode];
/*eslint no-cond-assign: 0*/
} else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
return String.fromCharCode(parseInt(match[1], 16));
/*eslint no-cond-assign: 0*/
} else if (match = entityCode.match(/^#(\d+)$/)) {
return String.fromCharCode(~~match[1]);
} else {
return entity;
}
});
};

HTML 特殊字符及其 ESCAPE CODES

保留字符必须通过 HTML 转义: 我们可以使用字符转义来表示 HTML、 XHTML 或 XML 中的任何 Unicode字符[ Ex: &-U + 00026] ,只使用 ASCII 字符。数字字符引用[ 例如:符号(&)-&#38;]和 名字字符引用[ Ex: &amp;]是 character escape used in markup的类型。


预定义实体

    Original Character     XML entity replacement    XML numeric replacement  
                  <                                    &lt;                                           &#60;                    
                  >                                     &gt;                                         &#62;                    
                  "                                     &quot;                                      &#34;                    
                  &                                   &amp;                                       &#38;                    
                   '                                    &apos;                                      &#39;                     < br/>

为了在网页中显示 HTML 标签作为一个正常的形式,我们使用 <pre><code>标签或者我们可以转义他们。通过将 "&"字符的任何匹配项替换为字符串 "&amp;"以及将 ">"字符的任何匹配项替换为字符串 "&gt;"来转义字符串。例句: stackoverflow post

function escapeCharEntities() {
var map = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
"\"": "&quot;",
"'": "&apos;"
};
return map;
}


var mapkeys = '', mapvalues = '';
var html = {
encodeRex : function () {
return  new RegExp(mapkeys, 'g'); // "[&<>"']"
},
decodeRex : function () {
return  new RegExp(mapvalues, 'g'); // "(&amp;|&lt;|&gt;|&quot;|&apos;)"
},
encodeMap : JSON.parse( JSON.stringify( escapeCharEntities () ) ), // json = {&: "&amp;", <: "&lt;", >: "&gt;", ": "&quot;", ': "&apos;"}
decodeMap : JSON.parse( JSON.stringify( swapJsonKeyValues( escapeCharEntities () ) ) ),
encode : function ( str ) {
var encodeRexs = html.encodeRex();
console.log('Encode Rex: ', encodeRexs); // /[&<>"']/gm
return str.replace(encodeRexs, function(m) { console.log('Encode M: ', m); return html.encodeMap[m]; }); // m = < " > SpecialChars
},
decode : function ( str ) {
var decodeRexs = html.decodeRex();
console.log('Decode Rex: ', decodeRexs); // /(&amp;|&lt;|&gt;|&quot;|&apos;)/g
return str.replace(decodeRexs, function(m) { console.log('Decode M: ', m); return html.decodeMap[m]; }); // m = &lt; &quot; &gt;
}
};


function swapJsonKeyValues ( json ) {
var count = Object.keys( json ).length;
var obj = {};
var keys = '[', val = '(', keysCount = 1;
for(var key in json) {
if ( json.hasOwnProperty( key ) ) {
obj[ json[ key ] ] = key;
keys += key;
if( keysCount < count ) {
val += json[ key ]+'|';
} else {
val += json[ key ];
}
keysCount++;
}
}
keys += ']';    val  += ')';
console.log( keys, ' == ', val);
mapkeys = keys;
mapvalues = val;
return obj;
}


console.log('Encode: ', html.encode('<input type="password" name="password" value=""/>') );
console.log('Decode: ', html.decode(html.encode('<input type="password" name="password" value=""/>')) );


O/P:
Encode:  &lt;input type=&quot;password&quot; name=&quot;password&quot; value=&quot;&quot;/&gt;
Decode:  <input type="password" name="password" value=""/>

如果希望多次避免对 html 实体进行编码

function encodeHTML(str){
return str.replace(/([\u00A0-\u9999<>&])(.|$)/g, function(full, char, next) {
if(char !== '&' || next !== '#'){
if(/[\u00A0-\u9999<>&]/.test(next))
next = '&#' + next.charCodeAt(0) + ';';


return '&#' + char.charCodeAt(0) + ';' + next;
}


return full;
});
}


function decodeHTML(str){
return str.replace(/&#([0-9]+);/g, function(full, int) {
return String.fromCharCode(parseInt(int));
});
}

# 例子

var text = "<a>Content &#169; <#>&<&#># </a>";


text = encodeHTML(text);
console.log("Encode 1 times: " + text);


// &#60;a&#62;Content &#169; &#60;#&#62;&#38;&#60;&#38;#&#62;# &#60;/a&#62;


text = encodeHTML(text);
console.log("Encode 2 times: " + text);


// &#60;a&#62;Content &#169; &#60;#&#62;&#38;&#60;&#38;#&#62;# &#60;/a&#62;


text = decodeHTML(text);
console.log("Decoded: " + text);


// <a>Content © <#>&<&#># </a>
var htmlEntities = [
{regex:/&/g,entity:'&amp;'},
{regex:/>/g,entity:'&gt;'},
{regex:/</g,entity:'&lt;'},
{regex:/"/g,entity:'&quot;'},
{regex:/á/g,entity:'&aacute;'},
{regex:/é/g,entity:'&eacute;'},
{regex:/í/g,entity:'&iacute;'},
{regex:/ó/g,entity:'&oacute;'},
{regex:/ú/g,entity:'&uacute;'}
];


total = <some string value>


for(v in htmlEntities){
total = total.replace(htmlEntities[v].regex, htmlEntities[v].entity);
}

数组解决方案

<!DOCTYPE html>
<html>
<style>
button {
backround: #ccc;
padding: 14px;
width: 400px;
font-size: 32px;
}
#demo {
font-size: 20px;
font-family: Arial;
font-weight: bold;
}
</style>
<body>


<p>Click the button to decode.</p>


<button onclick="entitycode()">Html Code</button>


<p id="demo"></p>




<script>
function entitycode() {
var uri = "quotation  = ark __ &apos; = apostrophe  __ &amp; = ampersand __ &lt; = less-than __ &gt; = greater-than __ 	non- = reaking space __ &iexcl; = inverted exclamation mark __ &cent; = cent __ &pound; = pound __ &curren; = currency __ &yen; = yen __ &brvbar; = broken vertical bar __ &sect; = section __ &uml; = spacing diaeresis __ &copy; = copyright __ &ordf; = feminine ordinal indicator __ &laquo; = angle quotation mark (left) __ &not; = negation __ &shy; = soft hyphen __ &reg; = registered trademark __ &macr; = spacing macron __ &deg; = degree __ &plusmn; = plus-or-minus  __ &sup2; = superscript 2 __ &sup3; = superscript 3 __ &acute; = spacing acute __ &micro; = micro __ &para; = paragraph __ &middot; = middle dot __ &cedil; = spacing cedilla __ &sup1; = superscript 1 __ &ordm; = masculine ordinal indicator __ &raquo; = angle quotation mark (right) __ &frac14; = fraction 1/4 __ &frac12; = fraction 1/2 __ &frac34; = fraction 3/4 __ &iquest; = inverted question mark __ &times; = multiplication __ &divide; = division __ &Agrave; = capital a, grave accent __ &Aacute; = capital a, acute accent __ &Acirc; = capital a, circumflex accent __ &Atilde; = capital a, tilde __ &Auml; = capital a, umlaut mark __ &Aring; = capital a, ring __ &AElig; = capital ae __ &Ccedil; = capital c, cedilla __ &Egrave; = capital e, grave accent __ &Eacute; = capital e, acute accent __ &Ecirc; = capital e, circumflex accent __ &Euml; = capital e, umlaut mark __ &Igrave; = capital i, grave accent __ &Iacute; = capital i, acute accent __ &Icirc; = capital i, circumflex accent __ &Iuml; = capital i, umlaut mark __ &ETH; = capital eth, Icelandic __ &Ntilde; = capital n, tilde __ &Ograve; = capital o, grave accent __ &Oacute; = capital o, acute accent __ &Ocirc; = capital o, circumflex accent __ &Otilde; = capital o, tilde __ &Ouml; = capital o, umlaut mark __ &Oslash; = capital o, slash __ &Ugrave; = capital u, grave accent __ &Uacute; = capital u, acute accent __ &Ucirc; = capital u, circumflex accent __ &Uuml; = capital u, umlaut mark __ &Yacute; = capital y, acute accent __ &THORN; = capital THORN, Icelandic __ &szlig; = small sharp s, German __ &agrave; = small a, grave accent __ &aacute; = small a, acute accent __ &acirc; = small a, circumflex accent __ &atilde; = small a, tilde __ &auml; = small a, umlaut mark __ &aring; = small a, ring __ &aelig; = small ae __ &ccedil; = small c, cedilla __ &egrave; = small e, grave accent __ &eacute; = small e, acute accent __ &ecirc; = small e, circumflex accent __ &euml; = small e, umlaut mark __ &igrave; = small i, grave accent __ &iacute; = small i, acute accent __ &icirc; = small i, circumflex accent __ &iuml; = small i, umlaut mark __ &eth; = small eth, Icelandic __ &ntilde; = small n, tilde __ &ograve; = small o, grave accent __ &oacute; = small o, acute accent __ &ocirc; = small o, circumflex accent __ &otilde; = small o, tilde __ &ouml; = small o, umlaut mark __ &oslash; = small o, slash __ &ugrave; = small u, grave accent __ &uacute; = small u, acute accent __ &ucirc; = small u, circumflex accent __ &uuml; = small u, umlaut mark __ &yacute; = small y, acute accent __ &thorn; = small thorn, Icelandic __ &yuml; = small y, umlaut mark";
var enc = encodeURI(uri);
var dec = decodeURI(enc);
var res = dec;
document.getElementById("demo").innerHTML = res;
}
</script>


</body>
</html>

看看来自 Ourcodeworld 的教程 Ourcodeworld-用 javascript 对 html 实体进行编码和解码

最重要的是 图书馆示例

he.encode('foo © bar ≠ baz ???? qux');
// → 'foo &#xA9; bar &#x2260; baz &#x1D306; qux'


// Passing an `options` object to `encode`, to explicitly encode all symbols:
he.encode('foo © bar ≠ baz ???? qux', {
'encodeEverything': true
});


he.decode('foo &copy; bar &ne; baz &#x1D306; qux');
// → 'foo © bar ≠ baz ???? qux'

这个库可能会使您的编码更容易和更好地管理。它很流行,定期更新,并遵循 HTML 规范。它本身没有依赖关系,可以在 包裹 Json中看到

下面是我如何实现编码的。我从上面给出的答案中获得了灵感。

function encodeHTML(str) {
const code = {
' ' : '&nbsp;',
'¢' : '&cent;',
'£' : '&pound;',
'¥' : '&yen;',
'€' : '&euro;',
'©' : '&copy;',
'®' : '&reg;',
'<' : '&lt;',
'>' : '&gt;',
'"' : '&quot;',
'&' : '&amp;',
'\'' : '&apos;'
};
return str.replace(/[\u00A0-\u9999<>\&''""]/gm, (i)=>code[i]);
}


// TEST
console.log(encodeHTML("Dolce & Gabbana"));
console.log(encodeHTML("Hamburgers < Pizza < Tacos"));
console.log(encodeHTML("Sixty > twelve"));
console.log(encodeHTML('Stuff in "quotation marks"'));
console.log(encodeHTML("Schindler's List"));
console.log(encodeHTML("<>"));

对 HTML 实体进行编码或解码的简易方法之一
只用一个参数调用一个函数..。

解码 HTML 实体

function decodeHTMLEntities(text) {
var textArea = document.createElement('textarea');
textArea.innerHTML = text;
return textArea.value;
}

解码 HTML 实体(JQuery)

function decodeHTMLEntities(text) {
return $("<textarea/>").html(text).text();
}

编码 HTML 实体

function encodeHTMLEntities(text) {
var textArea = document.createElement('textarea');
textArea.innerText = text;
return textArea.innerHTML;
}

编码 HTML 实体(JQuery)

function encodeHTMLEntities(text) {
return $("<textarea/>").text(text).html();
}

HTML 实体() 转换 HTML 实体

因此,我们构建一个常量,它将包含我们想要转换的 html 标记。

const htmlEntities = [
{regex:'&',entity:'&amp;'},
{regex:'>',entity:'&gt;'},
{regex:'<',entity:'&lt;'}
];

我们构建一个函数,将所有相应的 Html 字符转换为 String: Html = = > String

 function htmlentities (s){
var reg;
for (v in htmlEntities) {
reg = new RegExp(htmlEntities[v].regex, 'g');
s = s.replace(reg, htmlEntities[v].entity);
}
return s;
}

为了解码,我们构建了一个反向函数,将所有字符串转换为它们的等效 html。字符串 = = > html

 function  html_entities_decode (s){
var reg;
for (v in htmlEntities) {
reg = new RegExp(htmlEntities[v].entity, 'g');
s = s.replace(reg, htmlEntities[v].regex);
}
return s;
  

}

之后,我们可以用 encodeURIComponent ()对所有其他特殊字符(é...)进行编码

用例

 var s  = '<div> God bless you guy   </div> '
var h = encodeURIComponent(htmlentities(s));         /** To encode */
h =  html_entities_decode(decodeURIComponent(h));     /** To decode */
function htmlEntityReplacer(encoded_text) {
var decoded_text = encoded_text;


const all_entities = [{ /* source: https://www.w3schools.com/html/html_entities.asp */
encoded: `&nbsp;`,
decoded: ` `
}, {
encoded: `&lt;`,
decoded: `<`
}, {
encoded: `&gt;`,
decoded: `>`
}, {
encoded: `&amp;`,
decoded: `&`
}, {
encoded: `&quot;`,
decoded: `"`
}, {
encoded: `&apos;`,
decoded: `'`
}, {
encoded: `&cent;`,
decoded: `¢`
}, {
encoded: `&pound;`,
decoded: `£`
}, {
encoded: `&yen;`,
decoded: `yen`
}, {
encoded: `&euro;`,
decoded: `€`
}, {
encoded: `&copy;`,
decoded: `©`
}, {
encoded: `&reg;`,
decoded: `®`
}]
for (i = 0; i < all_entities.length; i++) {
var decoded_text = decoded_text.replace(new RegExp(all_entities[i].encoded, 'g'), all_entities[i].decoded)
}
return decoded_text;
}

//用于节点或香草

我想在这里分享我的解决方案给其他偶然发现这个帖子的读者。

我故意在这里转义引号,以便编码的值是“属性安全的”。<>也被有意地编码以便安全地避开任何 HTML 标记。

这是通过在 RegExp 上使用 u标志来实现的,该标志将匹配任何完整的 Unicode字符。我也使用 CodePointAt而不是 CharCodeAt,这样我就可以生成任何完整的 Unicode字符。然后,我确保任何匹配的字符都不是一组特定的 ASCII 字符,最后,对找到的每个 Unicode字符进行编码。

这也“忽略”任何当前转义的字符序列,通过匹配第一个字符序列。

function encodeHTMLEntities(str) {
if (!str)
return str;


// First:
//   Match any currently encoded characters first
//   (i.e. `&#67;`, `&#x43;`, or '&amp;')
//   Finally, match on any character with `.`, using
//   the `u` RegExp flag to match full Unicode code points.
// Second:
//   1) Already encoded characters must be at least four
//      characters (i.e. `&#1;`), and must start with an
//      '&' character. If this is true, then the match
//      is an already encoded character sequence, so just
//      return it.
//   2) Otherwise, see if the character is a single UTF-16
//      character, and is in our whitelist of allowed
//      characters (common ASCII, without quotes or < or >).
//      If this is the case, then don't encode the character,
//      and simply return it.
//   3) Finally, use codePointAt to encode the Unicode character.
return str.replace(/&#[0-9]+;|&#x[0-9a-fA-F]+;|&[0-9a-zA-Z]{2,};|./gu, (m) => {
// #1, is this an already encoded character sequence?
// If so, just return it.
if (m.length >= 4 && m[0] === '&')
return m;


// #2, is this one of our whitelisted ASCII characters
// (not including quotes or < or >)
if (m.length === 1 && m.match(/[a-zA-Z0-9\s\t\n\r~`!@#$%^&*_+=(){}[\]/\\,?:;|.-]/))
return m;


// #3 Otherwise, encode it as unicode
return `&#${m.codePointAt(0)};`;
});
}

例如:

console.log(encodeHTMLEntities('&amp; 😊 🙂 🎁 testing 🤣 &#x43; <stuff> "things" wow! &#67;'))

产出:

&amp; &#128522; &#128578; &#127873; testing &#129315; &#x43; &#60;stuff&#62; &#34;things&#34; wow! &#67;

在 NodeJs 上安装 html-entities

然后:

import {encode} from "html-entities";
encode(str);