在javascript中编码html实体
我在一个允许用户input内容的CMS中工作。 问题是,当他们添加符号®
,可能无法在所有浏览器中正常显示。 我想build立一个必须search的符号列表,然后转换为相应的html实体。 例如
®=> ®
&=> &
©=> ©
™=> ™
转换之后,它需要被包装在一个<sup>
标签中,导致:
®
=> <sup>®</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
- 使用Ruby on Rails构build的RefineryCMS
您可以使用正则expression式来replace给定Unicode范围中的任何字符与其相应的html实体。 代码看起来像这样:
var encodedStr = rawStr.replace(/[\u00A0-\u9999<>\&]/gim, function(i) { return '&#'+i.charCodeAt(0)+';'; });
这个代码将会用给定的范围(unicode 00A0 – 9999,以及和号,大于小于)replace它们的html实体等价物中的所有字符,这只是&#nnn;
其中nnn
是我们从charCodeAt
获得的unicode值。
在这里看到它的动作: http : //jsfiddle.net/E3EqX/13/ (这个例子使用jQuery作为示例中使用的元素select器,上面的基本代码本身不使用jQuery)
做这些转换并不能解决所有的问题 – 确保你使用UTF8字符编码,确保你的数据库以UTF8格式存储string。 您仍然可能会看到字符无法正确显示的情况,具体取决于系统字体configuration和其他您不能控制的问题。
文档
目前接受的答案有几个问题。 这篇文章解释了他们,并提供了更强大的解决scheme。 在答案中提出的解决scheme是:
var encodedStr = rawStr.replace(/[\u00A0-\u9999<>\&]/gim, function(i) { return '&#' + i.charCodeAt(0) + ';'; });
i
标志是多余的,因为从U + 00A0到U + 9999的范围内没有Unicode符号具有在相同范围之外的大写/小写变体。
m
标志是多余的,因为在正则expression式中不使用^
或$
。
为什么范围U + 00A0到U + 9999? 这似乎是任意的。
无论如何,对于input中包括安全&可打印的ASCII符号(包括星座符号!)在内的所有正确编码的解决scheme,并实现所有命名字符引用(不仅仅是HTML4中的那些),请使用他的库 (免责声明:这个库是我的)。 从它的README:
他 (用于“HTML实体”)是用JavaScript编写的健壮的HTML实体编码器/解码器。 它支持所有按照HTML标准化的命名字符引用 , 像浏览器一样处理不明确的&符号和其他边界情况,具有广泛的testing套件,与许多其他JavaScript解决scheme相反, 他处理的是星体Unicode符号。 在线演示可用。
也看到这个相关的堆栈溢出的答案 。
我有同样的问题,并创build了2个函数来创build实体并将其转换回正常字符。 以下方法将任何string转换为HTML实体并返回到String原型
/** * Convert a string to HTML entities */ String.prototype.toHtmlEntities = function() { return this.replace(/./gm, function(s) { return "&#" + 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: Dit is e´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æø𣨠ƒ™en t£eést String: Dit is e´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æø𣨠ƒ™en t£eést
没有任何库,如果你不需要支持IE <9,你可以创build一个html元素,并使用Node.textContent设置其内容:
var str = "<this is not a tag>"; var p = document.createElement("p"); p.textContent = str; var converted = p.innerHTML;
这里是一个例子: https : //jsfiddle.net/1erdhehv/
你可以使用这个。
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; } }); };
如果您已经在使用jQuery,请尝试html()
。
$('<div>').text('<script>alert("gotcha!")</script>').html() // "<script>alert("gotcha!")</script>"
内存中的文本节点被实例化,并调用html()
。
这是丑陋的,它浪费了一些内存,我不知道它是否像he
库一样彻底,但如果你已经使用jQuery,也许这是一个选项。
从博客文章中采用FelixGeisendörfer的jQuery对HTML实体进行编码 。
有时你只是想编码每个字符…这个函数替代regxp中的“什么都没有”。
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>
HTML特殊字符及其ESCAPE CODES
保留字符必须通过HTML转义:我们可以使用字符转义来表示任何使用ASCII字符的HTML,XHTML或XML中的任何Unicode字符[例如:& – U + 00026]。 数字字符引用 [ 例如: &符号(&) – &
]& 命名的字符引用 [例如: &
]是character escape used in markup
的character escape used in markup
types。
预定义的实体
原始字符 XML实体replace XML数字replace
< &lt; &#60;
> &gt; &#62;
“ &quot; &#34;
&&amp; &#38;
' ' &#39;
要在网页中以标准格式显示HTML标签,我们使用<pre>
, <code>
标签或者我们可以将它们转义。 用string"&"
replace任何出现的"&"
字符来转义string 以及string">"
出现的任何">"
字符 。 例如: stackoverflow post
function escapeCharEntities() { var map = { "&": "&", "<": "<", ">": ">", "\"": """, "'": "'" }; return map; } var mapkeys = '', mapvalues = ''; var html = { encodeRex : function () { return new RegExp(mapkeys, 'gm'); }, decodeRex : function () { return new RegExp(mapvalues, 'gm'); }, encodeMap : JSON.parse( JSON.stringify( escapeCharEntities () ) ), decodeMap : JSON.parse( JSON.stringify( swapJsonKeyValues( escapeCharEntities () ) ) ), encode : function ( str ) { return str.replace(html.encodeRex(), function(m) { return html.encodeMap[m]; }); }, decode : function ( str ) { return str.replace(html.decodeRex(), function(m) { return html.decodeMap[m]; }); } }; 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: <input type="password" name="password" value=""/> Decode: <input type="password" name="password" value=""/>
您可以使用charCodeAt()
方法来检查指定的字符是否具有高于127的值,并使用toString(16)
将其转换为数字字符引用。