[javascript] 자바 스크립트로 HTML 엔티티 인코딩

사용자가 콘텐츠를 입력 할 수있는 CMS에서 일하고 있습니다. 문제는 기호를 추가 할 때 ®모든 브라우저에서 제대로 표시되지 않을 수 있다는 것입니다. 검색해야하는 기호 목록을 설정 한 다음 해당 html 엔티티로 변환하고 싶습니다. 예를 들면

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

변환 후 <sup>태그 로 래핑해야 하므로 결과는 다음과 같습니다.

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

특정 글꼴 크기 및 패딩 스타일이 필요하기 때문에 :

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

자바 스크립트가 이와 비슷할까요?

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([?]);
}

여기서 “[?]”는 확실하지 않은 것이 있음을 의미합니다.

추가 세부 사항:

  • jQuery와 같은 라이브러리가 필요한 것이 아니라 순수한 JavaScript로이 작업을 수행하고 싶습니다. 감사합니다.
  • 백엔드는 Ruby입니다.
  • Ruby on Rails로 빌드 된 RefineryCMS 사용



답변

정규식을 사용하여 주어진 유니 코드 범위의 모든 문자를 해당하는 html 엔티티로 바꿀 수 있습니다. 코드는 다음과 같습니다.

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

단순히 인 자신의 HTML 엔티티 등가물로 -이 코드는 지정된 범위의 모든 문자 (9999뿐만 아니라, 앰퍼샌드, 큰 및 미만 유니 코드 00A0)를 대체 할 &#nnn;경우 nnn유니 코드 값을 우리가에서 얻을 수있다 charCodeAt.

: 여기에 직접보기 http://jsfiddle.net/E3EqX/13/ (이 예는 예에서 사용 된 요소 선택기 jQuery를 사용하는 기본 코드 자체, 위, jQuery를 사용하지 않습니다.)

이러한 변환을 수행한다고해서 모든 문제가 해결되는 것은 아닙니다. UTF8 문자 인코딩을 사용하고 있는지 확인하고 데이터베이스가 문자열을 UTF8로 저장하고 있는지 확인하세요. 당신은 여전히 문자가 당신의 통제 시스템 글꼴 설정 및 기타 문제에 따라 제대로 표시되지 않는 경우를 볼 수 있습니다.

선적 서류 비치


답변

현재 받아 들여지는 답변 에는 몇 가지 문제가 있습니다. 이 게시물에서는 이에 대해 설명하고보다 강력한 솔루션을 제공합니다. 이전에 그 답변에서 제안한 솔루션은 다음과 같습니다.

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

i플래그 U + U + 00A0에서 9999의 범위에는 유니 코드 심볼이 없기 때문에 중복 대문자 / 소문자 변형 밖에 동일한 범위된다.

m때문에 플래그는 중복 ^또는 $정규 표현식에서 사용되지 않습니다.

왜 U + 00A0에서 U + 9999까지의 범위입니까? 임의적으로 보입니다.

어쨌든, 입력에서 안전하고 인쇄 가능한 ASCII 기호 (아스트랄 기호 포함!)를 제외한 모든 것을 올바르게 인코딩 하고 모든 명명 된 문자 참조 (HTML4의 참조가 아님)를 구현 하는 솔루션의 경우 he 라이브러리를 사용하십시오 (면책 조항 :이 라이브러리는 내 것입니다). ). README에서 :

he ( “HTML 엔티티”의 경우)는 JavaScript로 작성된 강력한 HTML 엔티티 인코더 / 디코더입니다. 그것은 지원하는 HTML에 따라 모든 표준화라는 문자 참조를 , 핸들 모호한 앰퍼샌드 와 다른 에지의 경우 단지 브라우저 같은 것 , 광범위한 테스트 스위트 및이 – – 다른 많은 자바 스크립트 솔루션에 반하는 그가 잘 아스트랄 유니 코드 문자를 처리합니다. 온라인 데모를 사용할 수 있습니다.

이 관련 Stack Overflow 답변 도 참조하십시오 .


답변

나는 같은 문제가 있었고 엔티티를 생성하고 다시 일반 문자로 변환하는 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>


답변

HTML 특수 문자 및 해당 ESCAPE CODES

예약 된 문자는 HTML로 이스케이프해야합니다. ASCII 문자 만 사용하여 HTML, XHTML 또는 XML에서 유니 코드 문자 [예 : &-U + 00026]를 나타내는 데 문자 이스케이프를 사용할 수 있습니다. 숫자 참조 [ 예 : 앰퍼샌드 (&)- &#38;] & 명명 된 문자 참조 [예 : &amp;]는 character escape used in markup.


미리 정의 된 엔티티

    Original Character     XML entity replacement    XML numeric replacement  
                  <                                    &lt;                                           &#60;                    
                  >                                     &gt;                                         &#62;                    
                  "                                     &quot;                                      &#34;                    
                  &                                   &amp;                                       &#38;                    
                   '                                    &apos;                                      &#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=""/>