簡體   English   中英

在 JavaScript 中編碼 HTML 實體

[英]Encode HTML entities in JavaScript

我在一個允許用戶輸入內容的 CMS 中工作。 問題是當他們添加符號® ,它可能無法在所有瀏覽器中很好地顯示。 我想設置一個必須搜索的符號列表,然后轉換為相應的html實體。 例如

® => ®
& => &
© => ©
™ => ™

轉換后需要用<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
  • 使用由 Ruby on Rails 構建的 RefineryCMS

您可以使用正則表達式將給定 unicode 范圍內的任何字符替換為其等效的 html 實體。 代碼看起來像這樣:

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

此代碼將替換給定范圍內的所有字符(unicode 00A0 - 9999,以及&符號,大於和小於)與其等效的 html 實體,這只是&#nnn; 其中nnn是我們從charCodeAt獲得的 unicode 值。

在此處查看操作: http : //jsfiddle.net/E3EqX/13/ (此示例使用 jQuery 作為示例中使用的元素選擇器。上面的基本代碼本身不使用 jQuery)

進行這些轉換並不能解決所有問題——確保您使用的是 UTF8 字符編碼,確保您的數據庫以 UTF8 存儲字符串。 仍然可能會看到字符顯示不正確的情況,這取決於系統字體配置和您無法控制的其他問題。

文檔

當前接受的答案有幾個問題。 這篇文章解釋了它們,並提供了一個更強大的解決方案。 該答案中建議的解決方案以前有:

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

i標志是多余的,因為從 U+00A0 到 U+9999 范圍內的任何 Unicode 符號都沒有在同一范圍之外的大寫/小寫變體。

m標志是多余的,因為^$未在正則表達式中使用。

為什么范圍是 U+00A0 到 U+9999? 似乎是隨意的。

無論如何,對於在輸入中正確編碼除安全和可打印 ASCII 符號之外的所有符號(包括星形符號!)並實現所有命名字符引用(不僅僅是 HTML4 中的那些)的解決方案,請使用he(免責聲明:這個庫是我的) )。 從它的自述文件:

he (代表“HTML 實體”)是一個用 JavaScript 編寫的強大的 HTML 實體編碼器/解碼器。 它支持所有標准化的 HTML 命名字符引用像瀏覽器一樣處理模糊的&符號和其他邊緣情況,具有廣泛的測試套件,並且——與許多其他 JavaScript 解決方案相反——可以很好地處理星體 Unicode 符號。 提供在線演示。

另請參閱此相關堆棧溢出答案

我遇到了同樣的問題並創建了 2 個函數來創建實體並將它們轉換回正常字符。 以下方法將任何字符串轉換為 HTML 實體並返回字符串原型

/**
 * 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 

沒有任何庫,如果您不需要支持 IE < 9,您可以創建一個 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/

更新:這僅適用於 HTML 標記實體(&、< 和 >)。

你可以用這個。

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 實體

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>

如果您已經在使用 jQuery,請嘗試html()

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

實例化內存中的文本節點,並在其上調用html()

它很丑,浪費了一點內存,我不知道它是否像he庫一樣徹底,但如果你已經在使用 jQuery,也許這對你來說是一個選擇。

取自 Felix Geisendörfer 的博文Encode HTML entity with jQuery

HTML 特殊字符及其ESCAPE CODES

保留字符必須由 HTML 轉義:我們可以使用字符轉義來表示 HTML、XHTML 或 XML 中的任何 Unicode 字符 [例如:& - U+00026] 僅使用 ASCII 字符。 數字字符引用[例如: &#38; (&) - &#38; ] & 命名字符引用[例如: &amp; ] 是character escape used in markupcharacter escape used in markup類型。


預定義實體

原始字符XML 實體替換XML 數字替換
< &lt; &#60;
> &gt; &#62;
&quot; &#34;
& &amp; &#38;
' ' &#39;

為了在網頁中將 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=""/>
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);
}

陣列解決方案

有時您只想對每個字符進行編碼...此函數替換 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>

查看來自 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 規范。 它本身沒有依賴關系,可以在package.json 中看到

這是我實現編碼的方式。 我從上面給出的答案中獲得靈感。

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

htmlentities()轉換 HTML 實體

因此,我們構建了一個常量,其中包含我們要轉換的 html 標簽。

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

我們構建了一個函數,將所有相應的 html 字符轉換為字符串: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 */

函數 htmlEntityReplacer(encoded_text) { var decoded_text = encoding_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;

}

// 對於節點或香草

您可以使用charCodeAt()方法檢查指定字符的值是否大於 127,並使用toString(16)將其轉換為數字字符引用。

replaceHtmlEntities(text) {
  var tagsToReplace = {
    '&amp;': '&',
    '&lt;': '<',
    '&gt;': '>',
  };
  var newtext = text;
  for (var tag in tagsToReplace) {
    if (Reflect.apply({}.hasOwnProperty, this, [tagsToReplace, tag])) {
      var regex = new RegExp(tag, 'g');
      newtext = newtext.replace(regex, tagsToReplace[tag]);
    }
  }
  return newtext;
}

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM