Как мне избежать html в javascript? - PullRequest
23 голосов
/ 09 марта 2011

Учитывая текст

<b>This is some text</b>

Я хочу написать его на своей странице, чтобы он выглядел так:

<b>This is some text</b>

и не так

Это какой-то текст

с использованием escape("<b>This is some text</b>") дает мне этот прекрасный драгоценный камень в Firefox

%3Cb%3EThis%20is%20some%20text%3C/b%3E

не точно, что я ищу.Есть идеи?

Ответы [ 8 ]

58 голосов
/ 09 марта 2011

Это должно работать для вас: http://blog.nickburwell.com/2011/02/escape-html-tags-in-javascript.html

function escapeHTML( string )
{
    var pre = document.createElement('pre');
    var text = document.createTextNode( string );
    pre.appendChild(text);
    return pre.innerHTML;
}

Предупреждение безопасности

Функция не экранирует одинарные и двойные кавычки, которые при использовании в неправильном контексте могут привести к XSS. Например:

 var userWebsite = '" onmouseover="alert(\'gotcha\')" "';
 var profileLink = '<a href="' + escapeHtml(userWebsite) + '">Bob</a>';
 var div = document.getElemenetById('target');
 div.innerHtml = profileLink;
 // <a href="" onmouseover="alert('gotcha')" "">Bob</a>

Спасибо буфер за указание на этот случай. Фрагмент, извлеченный из этого сообщения в блоге .

25 голосов
/ 05 декабря 2013

Я закончил этим:

function escapeHTML(s) { 
    return s.replace(/&/g, '&amp;')
            .replace(/"/g, '&quot;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');
}
17 голосов
/ 22 июня 2015

Мне нравится ответ @ limc для ситуаций, когда доступен документ HTML DOM.

Мне нравятся ответы @Michele Bosi и @ Paolo для среды документов без HTML DOM, такой как Node.js.

@ Ответ Майкла Боси можно оптимизировать, устраняя необходимость вызывать замену 4 раза одним вызовом замены в сочетании с умной функцией заменителя:

function escape(s) {
    return s.replace(/[&"<>]/g, function (c) {
        return {
            '&': "&amp;",
            '"': "&quot;",
            '<': "&lt;",
            '>': "&gt;"
        }[c];
    });
}
console.log(escape("<b>This is some text.</b>"));

@ Тест диапазона Паоло может быть оптимизирован с помощью хорошо выбранного регулярного выражения, а цикл for можно устранить с помощью функции заменителя:

function escape(s) {
    return s.replace(/[^0-9A-Za-z ]/g, function(c) {
        return "&#" + c.charCodeAt(0) + ";";
    } );
}
console.log(escape("<b>This is some text</b>"));

Как указал @Paolo, эта стратегия будет работать для большего количества сценариев.

2 голосов
/ 26 июля 2015

Вы можете закодировать все символы в вашей строке:

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

Или просто нацеливайтесь на главных героев, о которых нужно беспокоиться (&, inebreaks, <,>, "и '), например:

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

test.value=encode('Encode HTML entities!\n\n"Safe" escape <script id=\'\'> & useful in <pre> tags!');

testing.innerHTML=test.value;

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55"></textarea>

<div id="testing">www.WHAK.com</div>
2 голосов
/ 01 июля 2013

Традиционный побег

Если вы используете XHTML, вам нужно использовать раздел CDATA.Вы также можете использовать их в HTML, но HTML не такой строгий.

Я разделил строковые константы, чтобы этот код работал внутри XHTML внутри блоков CDATA.Если вы используете свой JavaScript как отдельные файлы, вам не нужно беспокоиться об этом.Обратите внимание, что если вы используете XHTML со встроенным JavaScript, то вам нужно , чтобы заключить код в блок CDATA, или что-то из этого не будет работать.Вы столкнетесь с странными, тонкими ошибками.

function htmlentities(text) {
    var escaped = text.replace(/\]\]>/g, ']]' + '>]]&gt;<' + '![CDATA[');
    return '<' + '![CDATA[' + escaped + ']]' + '>';
}

Текстовый узел DOM

«Правильный» способ экранирования текста - использовать функцию DOM document.createTextNode.Это на самом деле не экранирует текст;он просто говорит браузеру создать текстовый элемент, который по своей сути не разбирается.Однако вы должны быть готовы использовать DOM для того, чтобы этот метод работал: то есть у вас есть такие методы, как appendChild, в отличие от свойства innerHTML и аналогичных.Это заполнит элемент с идентификатором an-element текстом, который не будет анализироваться как (X) HTML:

var textNode = document.createTextNode("<strong>This won't be bold.  The tags " +
    "will be visible.</strong>");
document.getElementById('an-element').appendChild(textNode);

jQuery DOM Wrapper

jQuery предоставляет удобную оболочку для createTextNode названный text.Это довольно удобно.Вот та же функциональность с использованием jQuery:

$('#an-element').text("<strong>This won't be bold.  The tags will be " +
    "visible.</strong>");
2 голосов
/ 09 марта 2011

Вот функция, которая заменяет угловые скобки их HTML-сущностями.Возможно, вы захотите расширить его, чтобы включить и другие символы.

function htmlEntities( html ) {
    html = html.replace( /[<>]/g, function( match ) {
        if( match === '<' ) return '&lt;';
        else return '&gt;';
    });
    return html;
}

console.log( htmlEntities( '<b>replaced</b>' ) ); // &lt;b&gt;replaced&lt;/b&gt;
2 голосов
/ 09 марта 2011

Попробуйте это htmlentities для JavaScript

function htmlEntities(str) {
    return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
1 голос
/ 27 декабря 2015

Я использую следующую функцию, которая экранирует каждый символ с помощью & # nnn ; , кроме az AZ 0-9 и пробел

function Escape( s )
{
    var h,
        i,
        n,
        c;

    n = s.length;
    h = '';

    for( i = 0; i < n; i++ )
    {
        c = s.charCodeAt( i );
        if( ( c >= 48 && c <= 57 ) 
          ||( c >= 65 && c <= 90 ) 
          ||( c >= 97 && c <=122 )
          ||( c == 32 ) )
        {
            h += String.fromCharCode( c );
        }
        else
        {
            h += '&#' + c + ';';
        }
    }

    return h;
}

Пример:

Escape('<b>This is some text</b>')

возвращает

&#60;b&#62;This is some text&#60;&#47;b&#62;

Функция защищена от атак с помощью внедрения кода, Unicode, чистый JavaScript.

Этот подход примерно в 50 раз медленнее , чем тот, который создает текстовый узел DOM, но при этом функция избегает строки в 1 миллион (1000000) символов за 100-150 миллисекунд.

(протестировано в начале 2011 года MacBook Pro - Safari 9 - Mavericks)

...