문제

문자열에서 HTML을 이스케이프하는 쉬운 방법을 아는 사람이 있습니까? jQuery?임의의 문자열을 전달하고 HTML 페이지에 표시하기 위해 적절하게 이스케이프 처리할 수 있어야 합니다(JavaScript/HTML 삽입 공격 방지).이 작업을 수행하기 위해 jQuery를 확장하는 것이 가능하다고 확신하지만 현재로서는 이를 수행할 수 있는 프레임워크에 대해 충분히 알지 못합니다.

도움이 되었습니까?

해결책

사용하기 때문에 jQuery, 당신은 요소를 설정할 수 있습니다 text 특성:

// before:
// <div class="someClass">text</div>
var someHtmlString = "<script>alert('hi!');</script>";

// set a DIV's text:
$("div.someClass").text(someHtmlString);
// after: 
// <div class="someClass">&lt;script&gt;alert('hi!');&lt;/script&gt;</div>

// get the text in a string:
var escaped = $("<div>").text(someHtmlString).html();
// value: 
// &lt;script&gt;alert('hi!');&lt;/script&gt;

다른 팁

도 있습니다 mustache.js의 솔루션

var entityMap = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};

function escapeHtml (string) {
  return String(string).replace(/[&<>"'`=\/]/g, function (s) {
    return entityMap[s];
  });
}
$('<div/>').text('This is fun & stuff').html(); // "This is fun &amp; stuff"

원천: http://debuggable.com/posts/encode-ncode-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbddd56cb

당신이 HTML을 탈출하고 있다면, 내가 생각할 수있는 세 가지만 있습니다.

html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");

유스 케이스에 따라 다음과 같은 작업을 수행해야 할 수도 있습니다. " 에게 &quot;. 목록이 충분히 커지면 배열 만 사용합니다.

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]
for(var item in findReplace)
    escaped = escaped.replace(findReplace[item][0], findReplace[item][1]);

encodeURIComponent() HTML이 아닌 URL에 대해서만 탈출합니다.

나는 이것을하는 작은 작은 기능을 썼다. 그것은 단지 탈출됩니다 ", &, < 그리고 > (그러나 보통 그게 어쨌든 필요한 전부입니다). 이전에 제안 된 솔루션보다 약간 더 우아합니다. 하나 .replace() 모든 변환을 수행합니다. (편집 2 : 코드 복잡성 감소 기능을 더 작고 깔끔하게 만드는 원래 코드가 궁금하다면이 답변의 끝을 참조하십시오.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&<>]/g, function (a) {
        return { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' }[a];
    });
}

이것은 평범한 JavaScript이며 jQuery가 사용되지 않았습니다.

탈출 / 그리고 ' ~도

응답으로 편집 mklement댓글.

위의 기능은 모든 문자를 포함하도록 쉽게 확장 될 수 있습니다. 탈출 할 더 많은 문자를 지정하려면 정규 표현식에 문자 클래스에 두 문자를 삽입하십시오 (즉, 내부의 내부 /[...]/g) 및 항목으로 chr 물체. (편집 2 : 같은 방식 으로이 기능도 단축되었습니다.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&'\/<>]/g, function (a) {
        return {
            '"': '&quot;', '&': '&amp;', "'": '&#39;',
            '/': '&#47;',  '<': '&lt;',  '>': '&gt;'
        }[a];
    });
}

위의 사용에 주목하십시오 &#39; 아포스트로피 (상징적 실체 &apos; 대신 사용되었을 수 있습니다 - XML에 정의되어 있지만 원래 HTML 사양에 포함되어 있지 않으므로 모든 브라우저에서 지원되지 않을 수 있습니다. 보다: HTML 문자 인코딩에 대한 Wikipedia 기사). 또한 10 진수 엔티티를 사용하는 것이 16 진수를 사용하는 것보다 더 널리 지원된다는 것을 읽는 것을 기억하지만 지금은 그 소스를 찾을 수는 없습니다. (그리고 16 진수를 지원하지 않는 많은 브라우저가있을 수 없습니다.)

메모: 첨가 / 그리고 ' 탈출 된 캐릭터 목록에는 HTML에 특별한 의미가없고 필요 탈출.

원래의 escapeHtml 기능

편집 2 : 원래 함수는 변수를 사용했습니다 (chr)에 필요한 개체를 저장합니다 .replace() 콜백. 이 변수는 또한 범위를 범위로 만들기 위해 추가 익명 기능이 필요하여 기능을 조금 더 크고 복잡하게 만듭니다.

var escapeHtml = (function () {
    'use strict';
    var chr = { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };
    return function (text) {
        return text.replace(/[\"&<>]/g, function (a) { return chr[a]; });
    };
}());

두 버전 중 어느 것이 더 빠른지 테스트하지 않았습니다. 그렇다면 여기에 정보와 링크를 추가하십시오.

밑줄을 사용하기에 쉽게 :

_.escape(string) 

밑줄 기본 JS가 제공하지 않는 많은 기능을 제공하는 유틸리티 라이브러리입니다. 또한 있습니다 Lodash 이것은 밑줄과 동일한 API이지만 더 성능이있는 것으로 다시 작성되었습니다.

나는 이 파티에 얼마나 늦었는지 알고 있지만 jQuery가 필요하지 않은 매우 쉬운 솔루션을 가지고 있습니다.

escaped = new Option(unescaped).innerHTML;

편집하다:이것은 따옴표를 벗어나지 않습니다.따옴표를 이스케이프해야 하는 유일한 경우는 콘텐츠를 HTML 문자열 내의 속성에 인라인으로 붙여넣는 경우입니다.이렇게 하는 것이 좋은 디자인이 될 경우는 상상하기 어렵습니다.

편집 2:성능이 중요한 경우 최고 성능 솔루션(약 50% 정도)은 여전히 ​​일련의 정규식 대체입니다.최신 브라우저는 정규 표현식에 연산자가 없고 문자열만 포함되어 있음을 감지하여 모든 표현식을 단일 작업으로 축소합니다.

다음은 깨끗하고 명확한 JavaScript 기능입니다. "몇 <많은"과 같은 텍스트를 "몇 <많은"으로 탈출합니다.

function escapeHtmlEntities (str) {
  if (typeof jQuery !== 'undefined') {
    // Create an empty div to use as a container,
    // then put the raw text in and get the HTML
    // equivalent out.
    return jQuery('<div/>').text(str).html();
  }

  // No jQuery, so use string replace.
  return str
    .replace(/&/g, '&amp;')
    .replace(/>/g, '&gt;')
    .replace(/</g, '&lt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;');
}

마지막 테스트 후 나는 추천 할 수 있습니다 가장 빠른 그리고 완전히 크로스 브라우저 호환 가능 기본 JavaScript (dom) 솔루션 :

function HTMLescape(html){
    return document.createElement('div')
        .appendChild(document.createTextNode(html))
        .parentNode
        .innerHTML
}

여러 번 반복하면 한 번 준비된 변수로 수행 할 수 있습니다.

//prepare variables
var DOMtext = document.createTextNode("test");
var DOMnative = document.createElement("span");
DOMnative.appendChild(DOMtext);

//main work for each case
function HTMLescape(html){
  DOMtext.nodeValue = html;
  return DOMnative.innerHTML
}

내 최종 공연을보세요 비교 (스택 질문).

노력하다 밑줄 lib, 그것은 jQuery와 함께 작동합니다.

_.str.escapeHTML('<div>Blah blah blah</div>')

산출:

'&lt;div&gt;Blah blah blah&lt;/div&gt;'

chustache.js 예제를 추가했습니다 escapeHTML() 문자열 객체에 대한 메소드.

var __entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
};

String.prototype.escapeHTML = function() {
    return String(this).replace(/[&<>"'\/]/g, function (s) {
        return __entityMap[s];
    });
}

그렇게하면 사용하기가 매우 쉽습니다 "Some <text>, more Text&Text".escapeHTML()

escape() 그리고 unescape() HTML이 아닌 URL의 문자열을 인코딩 / 디코딩하기위한 것입니다.

실제로, 나는 다음 스 니펫을 사용하여 프레임 워크가 필요하지 않은 트릭을 수행합니다.

var escapedHtml = html.replace(/&/g, '&amp;')
                      .replace(/>/g, '&gt;')
                      .replace(/</g, '&lt;')
                      .replace(/"/g, '&quot;')
                      .replace(/'/g, '&apos;');

aldscore.js가있는 경우 사용하십시오 _.escape (위에 게시 된 jQuery 방법보다 효율적) : :

_.escape('Curly, Larry & Moe'); // returns: Curly, Larry &amp; Moe

REGEX 경로를 사용하는 경우 위의 TGHW 예에 오류가 발생합니다.

<!-- WON'T WORK -  item[0] is an index, not an item -->

var escaped = html; 
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g,"&gt;"], [/"/g,
"&quot;"]]

for(var item in findReplace) {
     escaped = escaped.replace(item[0], item[1]);   
}


<!-- WORKS - findReplace[item[]] correctly references contents -->

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]

for(var item in findReplace) {
     escaped = escaped.replace(findReplace[item[0]], findReplace[item[1]]);
}

이것은 좋은 안전한 예입니다 ...

function escapeHtml(str) {
    if (typeof(str) == "string"){
        try{
            var newStr = "";
            var nextCode = 0;
            for (var i = 0;i < str.length;i++){
                nextCode = str.charCodeAt(i);
                if (nextCode > 0 && nextCode < 128){
                    newStr += "&#"+nextCode+";";
                }
                else{
                    newStr += "?";
                }
             }
             return newStr;
        }
        catch(err){
        }
    }
    else{
        return str;
    }
}

바닐라 JS로 쉽게 할 수 있습니다.

텍스트 노드를 추가하기 만하면 문서를 추가하십시오. 브라우저에 의해 탈출됩니다.

var escaped = document.createTextNode("<HTML TO/ESCAPE/>")
document.getElementById("[PARENT_NODE]").appendChild(escaped)
(function(undefined){
    var charsToReplace = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;'
    };

    var replaceReg = new RegExp("[" + Object.keys(charsToReplace).join("") + "]", "g");
    var replaceFn = function(tag){ return charsToReplace[tag] || tag; };

    var replaceRegF = function(replaceMap) {
        return (new RegExp("[" + Object.keys(charsToReplace).concat(Object.keys(replaceMap)).join("") + "]", "gi"));
    };
    var replaceFnF = function(replaceMap) {
        return function(tag){ return replaceMap[tag] || charsToReplace[tag] || tag; };
    };

    String.prototype.htmlEscape = function(replaceMap) {
        if (replaceMap === undefined) return this.replace(replaceReg, replaceFn);
        return this.replace(replaceRegF(replaceMap), replaceFnF(replaceMap));
    };
})();

글로벌 변수가없고 일부 메모리 최적화. 용법:

"some<tag>and&symbol©".htmlEscape({'©': '&copy;'})

결과는 다음과 같습니다.

"some&lt;tag&gt;and&amp;symbol&copy;"
function htmlEscape(str) {
    var stringval="";
    $.each(str, function (i, element) {
        alert(element);
        stringval += element
            .replace(/&/g, '&amp;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(' ', '-')
            .replace('?', '-')
            .replace(':', '-')
            .replace('|', '-')
            .replace('.', '-');
    });
    alert(stringval);
    return String(stringval);
}

jQuery가 필요없는 2 가지 간단한 방법 ...

당신은 할 수 있습니다 모든 문자를 인코딩합니다 다음과 같은 문자열에서 :

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

아니면 그냥 주인공을 대상으로합니다 에 대해서 걱정하다 &, 라인 브레이크, <, >, " 그리고 ' 처럼:

function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}

var myString='Encode HTML entities!\n"Safe" escape <script></'+'script> & other tags!';

test.value=encode(myString);

testing.innerHTML=encode(myString);

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<p><b>What JavaScript Generated:</b></p>

<textarea id=test rows="3" cols="55"></textarea>

<p><b>What It Renders Too In HTML:</b></p>

<div id="testing">www.WHAK.com</div>

일반 JavaScript Escaping 예 :

function escapeHtml(text) {
    var div = document.createElement('div');
    div.innerText = text;
    return div.innerHTML;
}

escapeHtml("<script>alert('hi!');</script>")
// "&lt;script&gt;alert('hi!');&lt;/script&gt;"
function htmlDecode(t){
   if (t) return $('<div />').html(t).text();
}

매력처럼 작동합니다

이 답변 jQuery 및 일반 JS 방법을 제공하지만 DOM을 사용하지 않고 가장 짧습니다.

unescape(escape("It's > 20% less complicated this way."))

탈출 된 문자열 : It%27s%20%3E%2020%25%20less%20complicated%20this%20way.

탈출 한 공간이 당신을 괴롭 히면 시도하십시오.

unescape(escape("It's > 20% less complicated this way.").replace(/%20/g, " "))

탈출 된 문자열 : It%27s %3E 20%25 less complicated this way.

불행히도, escape() 기능은 JavaScript 버전 1.5에서 더 이상 사용되지 않습니다. encodeURI() 또는 encodeURIComponent() 대안이지만 무시합니다 ', 마지막 코드 줄은 다음과 같습니다.

decodeURI(encodeURI("It's > 20% less complicated this way.").replace(/%20/g, " ").replace("'", '%27'))

모든 주요 브라우저는 여전히 짧은 코드를 지원하며 이전 웹 사이트의 수를 감안할 때 곧 변경 될 것입니다.

이 정보를 a에 저장하는 경우 데이터 베이스, a를 사용하여 HTML을 피하는 것은 잘못된 일입니다 고객 입장에서 스크립트, 이것은에서 수행해야합니다 섬기는 사람. 그렇지 않으면 XSS 보호를 우회하기가 쉽습니다.

내 요점을 명확하게하기 위해 여기에 답 중 하나를 사용하는 예는 다음과 같습니다.

블로그의 주석에서 HTML을 피한 다음 서버에 게시하는 기능 EscapeHtml 기능을 사용한다고 가정 해 봅시다.

var entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
  };

  function escapeHtml(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
      return entityMap[s];
    });
  }

사용자는 다음과 같습니다.

  • 게시물 요청 매개 변수를 편집하고 주석을 JavaScript 코드로 바꾸십시오.
  • 브라우저 콘솔을 사용하여 EscapeHtml 기능을 덮어 씁니다.

사용자 가이 스 니펫을 콘솔에 붙여 넣으면 XSS 유효성 검사를 우회합니다.

function escapeHtml(string){
   return string
}

재사용을 방지하지 않으면 모든 솔루션이 쓸모가 없습니다. 예를 들어 대부분의 솔루션은 계속 탈출합니다. & 에게 &amp;.

escapeHtml = function (s) {
    return s ? s.replace(
        /[&<>'"]/g,
        function (c, offset, str) {
            if (c === "&") {
                var substr = str.substring(offset, offset + 6);
                if (/&(amp|lt|gt|apos|quot);/.test(substr)) {
                    // already escaped, do not re-escape
                    return c;
                }
            }
            return "&" + {
                "&": "amp",
                "<": "lt",
                ">": "gt",
                "'": "apos",
                '"': "quot"
            }[c] + ";";
        }
    ) : "";
};
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top