Для «более точного»: этот рецепт в поваренной книге Python содержит алгоритмы суммирования, которые сохраняют полную точность (отслеживая промежуточные итоги). Код находится в Python, но даже если вы не знаете Python, достаточно ясно приспособиться к любому другому языку.
Все подробности приведены в этой статье .
Это должно работать для вас: 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>
Благодаря буферу за указание на этот случай. Фрагмент из этого поста в блоге .
Я закончил тем, что сделал это:
function escapeHTML(s) {
return s.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
}
Мне нравится ответ @ limc для ситуаций, когда доступен документ HTML DOM.
Мне нравятся ответы @Michele Bosi и @ Paolo для среды документов без HTML DOM, такой как Node.js.
@ Ответ Михаила Боси можно оптимизировать, устраняя необходимость вызывать замену 4 раза одним вызовом замены в сочетании с умной функцией заменителя:
function escape(s) {
return s.replace(/[&"<>]/g, function (c) {
return {
'&': "&",
'"': """,
'<': "<",
'>': ">"
}[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, эта стратегия будет работать для большего количества сценариев.
Вот функция, которая заменяет угловые скобки их HTML-сущностями. Возможно, вы захотите расширить его, включив в него и другие символы.
function htmlEntities( html ) {
html = html.replace( /[<>]/g, function( match ) {
if( match === '<' ) return '<';
else return '>';
});
return html;
}
console.log( htmlEntities( '<b>replaced</b>' ) ); // <b>replaced</b>
Попробуйте это htmlentities для JavaScript
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}
Если вы используете XHTML, вам нужно использовать раздел CDATA
. Вы также можете использовать их в HTML, но HTML не такой строгий.
Я разделил строковые константы, чтобы этот код работал внутри XHTML внутри блоков CDATA. Если вы используете свой JavaScript как отдельные файлы, вам не нужно беспокоиться об этом. Обратите внимание, что если вы используете XHTML со встроенным JavaScript, то вам нужно , чтобы заключить ваш код в блок CDATA, или что-то из этого не будет работать. Вы столкнетесь с странными, тонкими ошибками.
function htmlentities(text) {
var escaped = text.replace(/\]\]>/g, ']]' + '>]]><' + '![CDATA[');
return '<' + '![CDATA[' + escaped + ']]' + '>';
}
«Правильный» способ экранирования текста - использовать функцию 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 предоставляет удобную оболочку для createTextNode
по имени text
. Это довольно удобно. Вот та же функциональность с использованием jQuery:
$('#an-element').text("<strong>This won't be bold. The tags will be " +
"visible.</strong>");
Вы можете закодировать все символы в вашей строке:
function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
Или просто настроить целевые символы, о которых нужно беспокоиться (& amp ;, inebreaks, & lt ;,>, "и '), например:
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 &ersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55"></textarea>
<div id="testing">www.WHAK.com</div>
Я использую следующую функцию, которая экранирует каждый символ с нотациями & amp; # 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>')
возвращает
<b>This is some text</b>
Функция атак с внедрением кода доказательство, Unicode доказательство, чистый JavaScript.
Этот подход примерно в 50 раз медленнее , чем тот, который создает текстовый узел DOM, но, тем не менее, функция избегает строки длиной в один миллион (1 000 000) символов за 100-150 миллисекунд.
(протестировано в начале 2011 года MacBook Pro - Safari 9 - Mavericks)