Chcę wyświetlić tekst do HTML za pomocą funkcji javascript. Jak mogę uniknąć specjalnych znaków HTML w JS? Czy istnieje interfejs API?
Chcę wyświetlić tekst do HTML za pomocą funkcji javascript. Jak mogę uniknąć specjalnych znaków HTML w JS? Czy istnieje interfejs API?
Odpowiedzi:
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
replace()
połączeniach są niepotrzebne. Równie dobrze sprawdzą się zwykłe stare ciągi jednoznakowe.
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>'>
Możesz użyć .text()
funkcji jQuery .
Na przykład:
Z dokumentacji jQuery dotyczącej .text()
funkcji:
Musimy zdawać sobie sprawę, że ta metoda ucieka przed podanym ciągiem znaków, aby był poprawnie renderowany w HTML. W tym celu wywołuje metodę DOM .createTextNode (), nie interpretuje ciągu jako HTML.
Poprzednie wersje Dokumentacji jQuery sformułowały to w ten sposób ( wyróżnienie dodane ):
Musimy zdawać sobie sprawę, że ta metoda ucieka przed podanym ciągiem znaków, aby był poprawnie renderowany w HTML. W tym celu wywołuje metodę DOM .createTextNode (), która zastępuje znaki specjalne ich odpowiednikami encji HTML (np. & Lt; for <).
const str = "foo<>'\"&";
$('<div>').text(str).html()
wydajnościfoo<>'"&
Myślę, że znalazłem właściwy sposób, aby to zrobić ...
// 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
Za pomocą lodash
_.escape('fred, barney, & pebbles');
// => 'fred, barney, & pebbles'
To zdecydowanie najszybszy sposób, w jaki to widziałem. Ponadto robi to wszystko bez dodawania, usuwania lub zmieniania elementów na stronie.
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>'
Da niepoprawny HTML!
Ciekawe było znalezienie lepszego rozwiązania:
var escapeHTML = function(unsafe) {
return unsafe.replace(/[&<"']/g, function(m) {
switch (m) {
case '&':
return '&';
case '<':
return '<';
case '"':
return '"';
default:
return ''';
}
});
};
Nie analizuję, >
ponieważ nie psuje kodu XML / HTML w wyniku.
Oto testy: http://jsperf.com/regexpairs
Ponadto stworzyłem funkcję uniwersalną escape
: http://jsperf.com/regexpairs2
Najbardziej zwięzłym i wydajnym sposobem wyświetlania niekodowanego tekstu jest użycie textContent
właściwości.
Szybszy niż używanie innerHTML
. I to bez uwzględnienia ucieczki.
document.body.textContent = 'a <b> c </b>';
</
spełnienia sekwencji zamykającej .
Elementy DOM obsługują konwersję tekstu na HTML poprzez przypisanie do innerText . innerText nie jest funkcją, ale przypisywanie do niej działa tak, jakby tekst został poprzedzony znakiem ucieczki.
document.querySelectorAll('#id')[0].innerText = 'unsafe " String >><>';
<br>
elementy zamiast znaków nowej linii, które mogą rozkładać niektóre elementy, takie jak style lub skrypty. Nie createTextNode
jest podatny na ten problem.
innerText
ma pewne problemy ze starszymi wersjami / specyfikacjami. Lepszy w użyciu textContent
.
Możesz zakodować każdy znak w ciągu:
function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
Lub po prostu celuj w głównych bohaterów, aby się martwić (&, inebreaks, <,>, "i '), takich jak:
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>
Jednowarstwowy (dla ES6 +):
var escapeHtml = s => (s + '').replace(/[&<>"']/g, m => ({
'&': '&', '<': '<', '>': '>',
'"': '"', "'": '''
})[m]);
W przypadku starszych wersji:
function escapeHtml(s) {
return (s + '').replace(/[&<>"']/g, function (m) {
return ({
'&': '&', '<': '<', '>': '>',
'"': '"', "'": '''
})[m];
});
}
Ten problem pojawił się podczas tworzenia struktury DOM. To pytanie pomogło mi rozwiązać. Chciałem użyć podwójnego szewronu jako separatora ścieżki, ale dodanie nowego węzła tekstowego bezpośrednio spowodowało wyświetlenie kodu znaku ucieczki zamiast samego znaku:
var _div = document.createElement('div');
var _separator = document.createTextNode('»');
//_div.appendChild(_separator); /* this resulted in '»' being displayed */
_div.innerHTML = _separator.textContent; /* this was key */
Jeśli korzystasz już z modułów w swojej aplikacji, możesz użyć modułu Escape-HTML .
import escapeHtml from 'escape-html';
const unsafeString = '<script>alert("XSS");</script>';
const safeString = escapeHtml(unsafeString);
Wymyśliłem to rozwiązanie.
Załóżmy, że chcemy dodać do elementu trochę html z niebezpiecznymi danymi od użytkownika lub bazy danych.
var unsafe = 'some unsafe data like <script>alert("oops");</script> here';
var html = '';
html += '<div>';
html += '<p>' + unsafe + '</p>';
html += '</div>';
element.html(html);
Jest niebezpieczny przed atakami XSS. Teraz dodaj to.
$(document.createElement('div')).html(unsafe).text();
Tak jest
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);
Dla mnie jest to o wiele łatwiejsze niż używanie .replace()
i usunie !!! wszystkie możliwe tagi HTML (mam nadzieję).
<script>
w <script>
.