Bir javascript işlevi tarafından HTML metin görüntülemek istiyorum. JS'de html özel karakterlerinden nasıl kaçabilirim? Bir API var mı?
Bir javascript işlevi tarafından HTML metin görüntülemek istiyorum. JS'de html özel karakterlerinden nasıl kaçabilirim? Bir API var mı?
Yanıtlar:
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
replace()
Çağrılarda düzenli ifadelerin gereksiz olduğunu düşünüyorum . Sade eski tek karakterli dizeler de aynı şeyi yapardı.
function escapeHtml(html){
var text = document.createTextNode(html);
var p = document.createElement('p');
p.appendChild(text);
return p.innerHTML;
}
// Escape while typing & print result
document.querySelector('input').addEventListener('input', e => {
console.clear();
console.log( escapeHtml(e.target.value) );
});
<input style='width:90%; padding:6px;' placeholder='<b>cool</b>'>
JQuery .text()
işlevini kullanabilirsiniz .
Örneğin:
İşlevle ilgili jQuery belgelerinden .text()
:
HTML'de doğru şekilde görüntülenmesi için bu yöntemin gerektiği şekilde sağlanan dizeden kaçtığını bilmemiz gerekir. Bunu yapmak için .createTextNode () DOM yöntemini çağırır, dizeyi HTML olarak yorumlamaz.
JQuery Belgelerinin Önceki Sürümleri bunu şu şekilde ifade etmiştir ( vurgu eklenmiştir ):
HTML'de doğru şekilde görüntülenmesi için bu yöntemin gerektiği şekilde sağlanan dizeden kaçtığını bilmemiz gerekir. Bunu yapmak için, özel karakterleri HTML varlık eşdeğerleriyle (<için <<) değiştiren DOM .createTextNode () yöntemini çağırır .
const str = "foo<>'\"&";
$('<div>').text(str).html()
verimlerfoo<>'"&
Sanırım bunu yapmanın doğru yolunu buldum ...
// Create a DOM Text node:
var text_node = document.createTextNode(unescaped_text);
// Get the HTML element where you want to insert the text into:
var elem = document.getElementById('msg_span');
// Optional: clear its old contents
//elem.innerHTML = '';
// Append the text node into it:
elem.appendChild(text_node);
document.createTextNode("<script>alert('Attack!')</script>").textContent
Lodash kullanma
_.escape('fred, barney, & pebbles');
// => 'fred, barney, & pebbles'
Bu, şimdiye kadar, bunu yapmanın en hızlı yolu. Ayrıca, sayfadaki öğeleri eklemeden, çıkarmadan veya değiştirmeden hepsini yapar.
function escapeHTML(unsafeText) {
let div = document.createElement('div');
div.innerText = unsafeText;
return div.innerHTML;
}
var divCode = '<div data-title="' + escapeHTML('Jerry "Bull" Winston') + '">Div content</div>'
geçersiz HTML verir!
Daha iyi bir çözüm bulmak ilginçti:
var escapeHTML = function(unsafe) {
return unsafe.replace(/[&<"']/g, function(m) {
switch (m) {
case '&':
return '&';
case '<':
return '<';
case '"':
return '"';
default:
return ''';
}
});
};
>
Sonuçta XML / HTML kodunu bozmadığı için ayrıştırmadım .
İşte kriterler: http://jsperf.com/regexpairs
Ayrıca, evrensel bir escape
işlev oluşturdum : http://jsperf.com/regexpairs2
Kodlanmamış metni görüntülemenin en özlü ve en etkili yolu textContent
özelliği kullanmaktır .
Kullanmaktan daha hızlıinnerHTML
. Ve bu yükten kaçmayı hesaba katmadan.
document.body.textContent = 'a <b> c </b>';
</
DOM Elements, innerText öğesine atayarak metni HTML'ye dönüştürmeyi destekler . innerText bir işlev değildir, ancak atanması metin kaçmış gibi çalışır.
document.querySelectorAll('#id')[0].innerText = 'unsafe " String >><>';
<br>
, satırlar yerine stiller veya komut dosyaları gibi belirli öğeleri kırabilecek öğeler ekler . createTextNode
Bu sorunun eğilimli değildir.
innerText
bazı eski / spesifikasyon sorunları var. Kullanmak daha iyi textContent
.
Dizenizdeki her karakteri kodlayabilirsiniz:
function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
Veya endişelenmeniz gereken ana karakterleri hedefleyin (&, inebreaks, <,>, "ve '):
function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}
test.value=encode('How to encode\nonly html tags &<>\'" nice & fast!');
/*************
* \x26 is &ersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55">www.WHAK.com</textarea>
Bir astar (ES6 + için):
var escapeHtml = s => (s + '').replace(/[&<>"']/g, m => ({
'&': '&', '<': '<', '>': '>',
'"': '"', "'": '''
})[m]);
Eski sürümler için:
function escapeHtml(s) {
return (s + '').replace(/[&<>"']/g, function (m) {
return ({
'&': '&', '<': '<', '>': '>',
'"': '"', "'": '''
})[m];
});
}
Bir DOM yapısı oluştururken bu sorunla karşılaştım. Bu soru çözmeme yardımcı oldu. Bir yol ayırıcı olarak çift chevron kullanmak istedim, ancak yeni bir metin düğümü eklemek doğrudan karakterin kendisi yerine kaçan karakter kodu ile sonuçlandı:
var _div = document.createElement('div');
var _separator = document.createTextNode('»');
//_div.appendChild(_separator); /* this resulted in '»' being displayed */
_div.innerHTML = _separator.textContent; /* this was key */
Uygulamanızda zaten modüller kullanıyorsanız, escape-html modülünü kullanabilirsiniz.
import escapeHtml from 'escape-html';
const unsafeString = '<script>alert("XSS");</script>';
const safeString = escapeHtml(unsafeString);
Bu çözümü buldum.
Kullanıcıya veya veritabanından güvenli olmayan veriler içeren öğeye bazı html eklemek istediğimizi varsayalım.
var unsafe = 'some unsafe data like <script>alert("oops");</script> here';
var html = '';
html += '<div>';
html += '<p>' + unsafe + '</p>';
html += '</div>';
element.html(html);
XSS saldırılarına karşı güvenli değil. Şimdi bunu ekleyin.
$(document.createElement('div')).html(unsafe).text();
İşte bu
var unsafe = 'some unsafe data like <script>alert("oops");</script> here';
var html = '';
html += '<div>';
html += '<p>' + $(document.createElement('div')).html(unsafe).text(); + '</p>';
html += '</div>';
element.html(html);
Bana göre bu kullanmaktan çok daha kolay .replace()
ve kaldırılacak !!! tüm olası html etiketleri (umarım).
<script>
içine <script>
.