Odpowiedzi:
Uwaga bezpieczeństwa: użycie tej odpowiedzi (zachowanej w oryginalnej formie poniżej) może wprowadzić w aplikacji lukę w zabezpieczeniach XSS . Nie powinieneś używać tej odpowiedzi. Przeczytaj odpowiedź Lucasa na wyjaśnienie luk w tej odpowiedzi i zamiast tego użyj podejścia z tej odpowiedzi lub odpowiedzi Marka Ameryka .
Właściwie spróbuj
var decoded = $("<div/>").html(encodedStr).text();
$("<div/>").html('<img src="http://www.google.com/images/logos/ps_logo2.png" onload=alert(1337)>')
. W przeglądarce Firefox lub Safari uruchamia alert.
str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/g, "")
lub coś podobnego.
Bez jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
Działa to podobnie do zaakceptowanej odpowiedzi , ale można go bezpiecznie stosować przy niezaufanym wkładzie użytkownika.
Jak zauważył Mike Samuela , robi to z <div>
zamiast <textarea>
z niezaufanych danych wejściowych użytkownika jest luka XSS, nawet jeśli <div>
nigdy nie zostanie dodany do DOM:
function decodeEntities(encodedString) {
var div = document.createElement('div');
div.innerHTML = encodedString;
return div.textContent;
}
// Shows an alert
decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">')
Jednak ten atak nie jest możliwy przeciwko, <textarea>
ponieważ nie ma elementów HTML, które są dozwolone w treści <textarea>
. W związku z tym wszelkie tagi HTML wciąż obecne w ciągu „zakodowanego” zostaną automatycznie zakodowane przez przeglądarkę.
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
// Safe, and returns the correct answer
console.log(decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">'))
Ostrzeżenie : Robienie tego przy użyciu jQuery
.html()
i.val()
metod zamiast korzystania.innerHTML
i.value
jest również niepewne * dla niektórych wersji jQuery, nawet gdy używasztextarea
. Wynika to z faktu, że starsze wersje jQuery celowo i jawnie oceniały skrypty zawarte w przekazywanym ciągu.html()
. Dlatego taki kod pokazuje alert w jQuery 1.8:
//<!-- CDATA
// Shows alert
$("<textarea>")
.html("<script>alert(1337);</script>")
.text();
//-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
* Podziękowania dla Eru Penkman za wyłapanie tej podatności.
decodedString = textArea.value;
textArea.remove();
return decodedString;
if ('remove' in Element.prototype) textArea.remove();
$("<div />").html(string).text()
wykona dowolny kod JavaScript w podanym ciągu , co, jak podejrzewam, jest przyczyną problemu. Przyjęta odpowiedź powinna zostać zaktualizowana do tej.
Jak powiedział Mike Samuel, nie używaj jQuery.html (). Text () do dekodowania jednostek HTML, ponieważ jest to niebezpieczne.
Zamiast tego użyj renderera szablonów, takiego jak Mustache.js lub decodeEntities z komentarza @ VyvIT.
Underscore.js biblioteka narzędzie pas wyposażony escape
i unescape
metod, ale nie są one bezpieczne dla danych wejściowych użytkownika:
unescape
tej pory włączali się do dokumentów, btw.
_.unescape("'")
powoduje tylko „& # 39;” zamiast pojedynczego cytatu. Czy brakuje mi czegoś lub podkreślenie nie powoduje ucieczki do kodów encji HTML, jak pokazano na: w3schools.com/tags/ref_entities.asp
escape
i unescape
metody… nie są bezpieczne dla danych wprowadzanych przez użytkownika” . Co przez to rozumiesz? Dla mnie to brzmi jak nonsens, ale może coś mi brakuje - czy możesz to wyjaśnić?
_.unescape("<img src=fake onerror=alert('boo!')>")
(w Chrome / FF / IE). Ale to nie pokazało żadnego ostrzeżenia. Wypróbowałem to w konsoli, a także umieściłem w moim pliku JS. Ten sam wynik.
Myślę, że mylisz metody tekstowe i HTML. Spójrz na ten przykład, jeśli użyjesz wewnętrznego HTML elementu jako tekstu, otrzymasz dekodowane tagi HTML (drugi przycisk). Ale jeśli użyjesz ich jako HTML, otrzymasz widok w formacie HTML (pierwszy przycisk).
<div id="myDiv">
here is a <b>HTML</b> content.
</div>
<br />
<input value="Write as HTML" type="button" onclick="javascript:$('#resultDiv').html($('#myDiv').html());" />
<input value="Write as Text" type="button" onclick="javascript:$('#resultDiv').text($('#myDiv').html());" />
<br /><br />
<div id="resultDiv">
Results here !
</div>
Pierwszy przycisk pisze: oto treść HTML .
Drugi przycisk pisze: oto treść <B> HTML </B>.
Nawiasem mówiąc, możesz zobaczyć wtyczkę, którą znalazłem we wtyczce jQuery - Dekodowanie i kodowanie HTML, które koduje i dekoduje ciągi HTML.
Pytanie jest ograniczone przez „with jQuery”, ale może pomóc niektórym wiedzieć, że kod jQuery podany w najlepszej tutaj odpowiedzi ma następujące cechy ... działa to z lub bez jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
Możesz skorzystać z biblioteki on , dostępnej na stronie https://github.com/mathiasbynens/he
Przykład:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
I zakwestionował autor biblioteki na pytanie, czy istnieje jakikolwiek powód, aby korzystać z tej biblioteki w kodzie stronie klienta na rzecz <textarea>
hack, przewidzianej w innych odpowiedzi tutaj i gdzie indziej. Podał kilka możliwych uzasadnień:
Jeśli używasz strony node.js po stronie serwera, użycie biblioteki do kodowania / dekodowania HTML daje jedno rozwiązanie, które działa zarówno po stronie klienta, jak i po stronie serwera.
Algorytmy dekodowania encji niektórych przeglądarek zawierają błędy lub brakuje obsługi niektórych nazwanych odwołań do znaków . Na przykład Internet Explorer zarówno
poprawnie dekoduje, jak i renderuje spacje nierozdzielające ( ), ale zgłasza je jako spacje zwykłe zamiast nierozdzielających za pomocą innerText
właściwości elementu DOM , przerywając <textarea>
włamanie (choć tylko w niewielkim stopniu). Ponadto IE 8 i 9 po prostu nie obsługują żadnego z nowych nazwanych odniesień do znaków dodanych w HTML 5. Autor jego również organizuje test obsługi nazwanych odniesień do znaków na stronie http://mathias.html5.org/tests/html / names-character-reference / . W IE 8 zgłasza ponad tysiąc błędów.
Jeśli chcesz być izolowany od błędów przeglądarki związanych z dekodowaniem encji i / lub być w stanie obsłużyć pełny zakres odniesień do nazwanych postaci, nie możesz uciec od <textarea>
włamania; potrzebujesz biblioteki takiej jak on .
Po prostu dobrze się czuje, że robienie rzeczy w ten sposób jest mniej hackerskie.
kodować:
$("<textarea/>").html('<a>').html(); // return '<a>'
rozszyfrować:
$("<textarea/>").html('<a>').val() // return '<a>'
Posługiwać się
myString = myString.replace( /\&/g, '&' );
Najłatwiej jest to zrobić po stronie serwera, ponieważ najwyraźniej JavaScript nie ma natywnej biblioteki do obsługi encji, ani nie znalazłem żadnej w górnej części wyników wyszukiwania dla różnych struktur rozszerzających JavaScript.
Wyszukaj „JavaScript HTML encities”, a może znajdziesz kilka bibliotek tylko do tego celu, ale prawdopodobnie wszystkie one zostaną zbudowane wokół powyższej logiki - zamień encję po encji.
Po prostu musiałem mieć charater encji HTML (⇓) jako wartość dla przycisku HTML. Kod HTML wygląda dobrze od samego początku w przeglądarce:
<input type="button" value="Embed & Share ⇓" id="share_button" />
Teraz dodałem przełącznik, który powinien również wyświetlać znak. To jest moje rozwiązanie
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
Wyświetli się ponownie the w przycisku. Mam nadzieję, że to może komuś pomóc.
"Embed & Share \u21d1"
) Lub jeszcze lepiej, tylko "Embed & Share ⇑"
jeśli jesteś w stanie obsłużyć swój skrypt w UTF-8 (lub UTF-16 lub innym kodowaniu, które obsługuje znak ⇑). Wykorzystanie elementu DOM do parsowania encji HTML tylko w celu upieczenia dowolnego znaku Unicode w ciągu JavaScript jest sprytnym i kreatywnym podejściem, które sprawiłoby, że Rube Goldberg byłby dumny, ale nie jest dobrą praktyką; sekwencje specjalne unicode są w języku specjalnie do obsługi tego przypadku użycia.
Musisz stworzyć niestandardową funkcję dla encji HTML:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Załóżmy, że masz poniżej String.
Nasze kabiny Deluxe są ciepłe, przytulne i wyposażone; wygodny
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str i przypisz z powrotem do
etykietka.
Otóż to.
W przypadku użytkowników ExtJS, jeśli masz już zakodowany ciąg, na przykład gdy zwróconą wartością funkcji bibliotecznej jest zawartość innerHTML, rozważ tę funkcję ExtJS:
Ext.util.Format.htmlDecode(innerHtmlContent)
Rozszerz klasę String:
String::decode = ->
$('<textarea />').html(this).text()
i użyj jako metody:
"<img src='myimage.jpg'>".decode()
Spróbuj tego :
var htmlEntities = "<script>alert('hello');</script>";
var htmlDecode =$.parseHTML(htmlEntities)[0]['wholeText'];
console.log(htmlDecode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
parseHTML jest funkcją w bibliotece Jquery i zwraca tablicę, która zawiera pewne szczegóły dotyczące danego ciągu.
w niektórych przypadkach łańcuch jest duży, więc funkcja podzieli zawartość na wiele indeksów.
i aby uzyskać wszystkie dane indeksów, należy przejść do dowolnego indeksu, a następnie uzyskać dostęp do indeksu o nazwie „wholeText”.
Wybrałem indeks 0, ponieważ będzie on działał we wszystkich przypadkach (mały ciąg lub duży ciąg).
Pozostaje jeszcze jeden problem: Ciąg znaków ucieczki nie wygląda na czytelny po przypisaniu do wartości wejściowej
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Przykład: https://jsfiddle.net/kjpdwmqa/3/
escape
metody Underscore.js. Nie ma też wyjaśnienia, w jaki sposób próbka kodu powinna rozwiązać problem OP.
Alternatywnie jest też biblioteka dla niego ..
tutaj https://cdnjs.com/libraries/he
npm install he //using node.js
<script src="js/he.js"></script> //or from your javascript directory
Użycie jest następujące ...
//to encode text
he.encode('© Ande & Nonso® Company LImited 2018');
//to decode the
he.decode('© Ande & Nonso® Company Limited 2018');
Twoje zdrowie.
Aby zdekodować encje HTML za pomocą jQuery, wystarczy użyć tej funkcji:
function html_entity_decode(txt){
var randomID = Math.floor((Math.random()*100000)+1);
$('body').append('<div id="random'+randomID+'"></div>');
$('#random'+randomID).html(txt);
var entity_decoded = $('#random'+randomID).html();
$('#random'+randomID).remove();
return entity_decoded;
}
Jak używać:
JavaScript:
var txtEncoded = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />
Najprostszym sposobem jest ustawienie selektora klasy na elementy, a następnie użycie następującego kodu:
$(function(){
$('.classSelector').each(function(a, b){
$(b).html($(b).text());
});
});
Nic więcej nie jest potrzebne!
Miałem ten problem i znalazłem to jasne rozwiązanie, które działa dobrze.