programing tip

Javascript에서 HtmlSpecialChars가 동일합니까?

itbloger 2020. 6. 5. 20:21
반응형

Javascript에서 HtmlSpecialChars가 동일합니까?


분명히, 이것은 내가 생각했던 것보다 찾기가 어렵습니다. 그리고 심지어 너무 간단합니다 ...

Javascript에 내장 된 PHP의 htmlspecialchars와 동등한 기능이 있습니까? 나는 그것을 직접 구현하는 것이 상당히 쉽다는 것을 알고 있지만 가능한 경우 내장 함수를 사용하는 것이 더 좋습니다.

PHP에 익숙하지 않은 사람들을 위해, 반드시 htmlspecialchars처럼 물건을 변환 <htmltag/>&lt;htmltag/&gt;

나도 알아 escape()하고 encodeURI()이런 식으로 작동하지 않습니다.


솔루션 코드에 문제가 있습니다. 각 특수 문자의 첫 번째 항목 만 이스케이프합니다. 예를 들면 다음과 같습니다.

escapeHtml('Kip\'s <b>evil</b> "test" code\'s here');
Actual:   Kip&#039;s &lt;b&gt;evil</b> &quot;test" code's here
Expected: Kip&#039;s &lt;b&gt;evil&lt;/b&gt; &quot;test&quot; code&#039;s here

다음은 올바르게 작동하는 코드입니다.

function escapeHtml(text) {
  return text
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
}

최신 정보

다음 코드는 위와 동일한 결과를 생성하지만 특히 큰 텍스트 블록 ( jbo5112 덕분에 ) 에서 더 잘 수행 됩니다.

function escapeHtml(text) {
  var map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };

  return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}

HTML 인코딩입니다. 이를 수행하는 기본 자바 스크립트 기능은 없지만 Google을 사용하여 멋지게 완성 할 수 있습니다.

예 : http://sanzon.wordpress.com/2008/05/01/neat-little-html-encoding-trick-in-javascript/

편집 :
이것은 내가 테스트 한 것입니다 :

var div = document.createElement('div');
  var text = document.createTextNode('<htmltag/>');
  div.appendChild(text);
  console.log(div.innerHTML);

산출: &lt;htmltag/&gt;


읽을만한 가치 : http://bigdingus.com/2007/12/29/html-escaping-in-javascript/

escapeHTML: (function() {
 var MAP = {
   '&': '&amp;',
   '<': '&lt;',
   '>': '&gt;',
   '"': '&#34;',
   "'": '&#39;'
 };
  var repl = function(c) { return MAP[c]; };
  return function(s) {
    return s.replace(/[&<>'"]/g, repl);
  };
})()

참고 : 한 번만 실행하십시오. 그리고 예를 들어 이미 인코딩 된 문자열에서 실행하지 않는 &amp;된다&amp;amp;


jQuery를 사용하면 다음과 같이 될 수 있습니다.

var escapedValue = $('<div/>').text(value).html();

관련 질문 에서 jQuery로 HTML 문자열 이스케이프

주석에서 언급 했듯이이 구현에서는 큰 따옴표와 작은 따옴표가 그대로 남아 있습니다. 즉, 요소 ​​속성을 원시 HTML 문자열로 만들어야하는 경우이 솔루션을 사용해서는 안됩니다.


HTML을 이스케이프 처리하는 기능은 다음과 같습니다.

function escapeHtml(str)
{
    var map =
    {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
    };
    return str.replace(/[&<>"']/g, function(m) {return map[m];});
}

그리고 해독 :

function decodeHtml(str)
{
    var map =
    {
        '&amp;': '&',
        '&lt;': '<',
        '&gt;': '>',
        '&quot;': '"',
        '&#039;': "'"
    };
    return str.replace(/&amp;|&lt;|&gt;|&quot;|&#039;/g, function(m) {return map[m];});
}

Underscore.js는이를위한 기능을 제공합니다.

_.escape(string)

&, <,>, "및 '문자를 대체하여 HTML에 삽입 할 문자열을 이스케이프합니다.

http://underscorejs.org/#escape

내장 Javascript 함수는 아니지만 이미 Underscore를 사용하고 있다면 변환 할 문자열이 너무 크지 않은 경우 자체 함수를 작성하는 것보다 더 나은 대안입니다.


또 다른 점은 모든 문자 매핑을 모두 버리고 대신 원치 않는 문자를 각각의 숫자 참조로 변환하는 것입니다. 예 :

function escapeHtml(raw) {
    return raw.replace(/[&<>"']/g, function onReplace(match) {
        return '&#' + match.charCodeAt(0) + ';';
    });
}

Note that the specified RegEx only handles the specific characters that the OP wanted to escape but, depending on the context that the escaped HTML is going to be used, these characters may not be sufficient. Ryan Grove’s article There's more to HTML escaping than &, <, >, and " is a good read on the topic. And depending on your context, the following RegEx may very well be needed in order to avoid XSS injection:

var regex = /[&<>"'` !@$%()=+{}[\]]/g

String.prototype.escapeHTML = function() {
        return this.replace(/&/g, "&amp;")
                   .replace(/</g, "&lt;")
                   .replace(/>/g, "&gt;")
                   .replace(/"/g, "&quot;")
                   .replace(/'/g, "&#039;");
    }

sample :

var toto = "test<br>";
alert(toto.escapeHTML());

Chances are you don't need such a function. Since your code is already in the browser*, you can access the DOM directly instead of generating and encoding HTML that will have to be decoded backwards by the browser to be actually used.

Use innerText property to insert plain text into the DOM safely and much faster than using any of the presented escape functions. Even faster than assigning a static preencoded string to innerHTML.

Use classList to edit classes, dataset to set data- attributes and setAttribute for others.

All of these will handle escaping for you. More precisely, no escaping is needed and no encoding will be performed underneath**, since you are working around HTML, the textual representation of DOM.

// use existing element
var author = 'John "Superman" Doe <john@example.com>';
var el = document.getElementById('first');
el.dataset.author = author;
el.textContent = 'Author: '+author;

// or create a new element
var a = document.createElement('a');
a.classList.add('important');
a.href = '/search?q=term+"exact"&n=50';
a.textContent = 'Search for "exact" term';
document.body.appendChild(a);

// actual HTML code
console.log(el.outerHTML);
console.log(a.outerHTML);
.important { color: red; }
<div id="first"></div>

* This answer is not intended for server-side JavaScript users (Node.js, etc.)

** Unless you explicitly convert it to actual HTML afterwards. E.g. by accessing innerHTML - this is what happens when you run $('<div/>').text(value).html(); suggested in other answers. So if your final goal is to insert some data into the document, by doing it this way you'll be doing the work twice. Also you can see that in the resulting HTML not everything is encoded, only the minimum that is needed for it to be valid. It is done context-dependently, that's why this jQuery method doesn't encode quotes and therefore should not be used as a general purpose escaper. Quotes escaping is needed when you're constructing HTML as a string with untrusted or quote-containing data at the place of an attribute's value. If you use the DOM API, you don't have to care about escaping at all.


For Node.JS users (or users utilizing Jade runtime in the browser), you can use Jade's escape function.

require('jade').runtime.escape(...);

No sense in writing it yourself if someone else is maintaining it. :)


function htmlspecialchars(str) {
 if (typeof(str) == "string") {
  str = str.replace(/&/g, "&amp;"); /* must do &amp; first */
  str = str.replace(/"/g, "&quot;");
  str = str.replace(/'/g, "&#039;");
  str = str.replace(/</g, "&lt;");
  str = str.replace(/>/g, "&gt;");
  }
 return str;
 }

Hope this wins the race due to its performance and most important not a chained logic using .replace('&','&').replace('<','<')...

var mapObj = {
   '&':"&amp;",
   '<':"&lt;",
   '>':"&gt;",
   '"':"&quot;",
   '\'':"&#039;"
};
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");

function escapeHtml(str) 
{   
    return str.replace(re, function(matched)
    {
        return mapObj[matched.toLowerCase()];
    });
}

console.log('<script type="text/javascript">alert('Hello World');</script>');
console.log(escapeHtml('<script type="text/javascript">alert('Hello World');</script>'));

Reversed one:

function decodeHtml(text) {
    return text
        .replace(/&amp;/g, '&')
        .replace(/&lt;/ , '<')
        .replace(/&gt;/, '>')
        .replace(/&quot;/g,'"')
        .replace(/&#039;/g,"'");
}

I am elaborating a bit on o.k.w.'s answer.

You can use the browser's DOM functions for that.

var utils = {
    dummy: document.createElement('div'),
    escapeHTML: function(s) {
        this.dummy.textContent = s
        return this.dummy.innerHTML
    }
}

utils.escapeHTML('<escapeThis>&')

This returns &lt;escapeThis&gt;&amp;

It uses the standard function createElement to create an invisible element, then uses the function textContent to set any string as its content and then innerHTML to get the content in its HTML representation.


function htmlEscape(str){
    return str.replace(/[&<>'"]/g,x=>'&#'+x.charCodeAt(0)+';')
}

This solution uses the numerical code of the characters, for example < is replaced by &#60;.

Although its performance is slightly worse than the solution using a map, it has the advantages:

  • Not dependent on a library or DOM
  • Pretty easy to remember (you don't need to memorize the 5 HTML escape characters)
  • Little code
  • Reasonably fast (it's still faster than 5 chained replace)

참고URL : https://stackoverflow.com/questions/1787322/htmlspecialchars-equivalent-in-javascript

반응형