Mam ciągi jak
var str = 'One & two & three';
renderowane do HTML przez serwer WWW. Muszę przekształcić te ciągi
'One & two & three'
Obecnie to właśnie robię (przy pomocy jQuery):
$(document.createElement('div')).html('{{ driver.person.name }}').text()
Mam jednak niepokojące wrażenie, że robię to źle. próbowałem
unescape("&")
ale wydaje się, że to nie działa, podobnie jak decodeURI / decodeURIComponent.
Czy istnieją inne, bardziej rodzime i eleganckie sposoby na zrobienie tego?
javascript
html
text
decode
Sztuka
źródło
źródło
escape
d lub URI , funkcje te nie będą działać.𝕫
. Jest to problem związany ze zmieniającą się specyfikacją; dlatego powinieneś wybrać narzędzie, które faktycznie jest utrzymywane, aby je rozwiązać.Odpowiedzi:
Bardziej nowoczesną opcją interpretacji HTML (tekst i inne) z JavaScript jest obsługa HTML w
DOMParser
API ( patrz tutaj w MDN ). Pozwala to na użycie natywnego parsera HTML przeglądarki do konwersji ciągu znaków na dokument HTML. Jest obsługiwany w nowych wersjach wszystkich głównych przeglądarek od końca 2014 roku.Jeśli chcemy po prostu odkodować część tekstu, możemy umieścić go jako jedyną treść w treści dokumentu, przeanalizować dokument i wyciągnąć z niego
.body.textContent
.Widzimy w specyfikacji roboczej,
DOMParser
że JavaScript nie jest włączony dla analizowanego dokumentu, więc możemy wykonać tę konwersję tekstu bez obaw związanych z bezpieczeństwem.To wykracza poza zakres tego pytania, ale pamiętaj, że jeśli weźmiesz parsowane węzły DOM (nie tylko ich treść tekstową) i przeniesiesz je do DOM dokumentu na żywo, możliwe, że ich skrypty zostaną ponownie włączone, i może mieć obawy dotyczące bezpieczeństwa. Nie badałem tego, więc zachowaj ostrożność.
źródło
Czy musisz zdekodować wszystkie zakodowane jednostki HTML, czy tylko
&
sam?Jeśli potrzebujesz tylko obsługiwać,
&
możesz to zrobić:Jeśli musisz zdekodować wszystkie jednostki HTML, możesz to zrobić bez jQuery:
Zwróć uwagę na komentarze Marka poniżej, które podkreślają luki w zabezpieczeniach we wcześniejszej wersji tej odpowiedzi i zalecają stosowanie
textarea
zamiastdiv
łagodzenia potencjalnych luk w zabezpieczeniach XSS. Luki te występują niezależnie od tego, czy używasz jQuery, czy zwykłego JavaScript.źródło
encoded='<img src="bla" onerror="alert(1)">'
następnie powyższy fragment pokaże alert. Oznacza to, że jeśli zakodowany tekst pochodzi z danych wprowadzonych przez użytkownika, dekodowanie go za pomocą tego fragmentu kodu może stanowić lukę w zabezpieczeniach XSS.null
po otrzymaniu tekstu, alert w img nie zostanie wyzwolonyalert(1)
nadal działa dla mnie w Chrome na OS X. Jeśli chcesz bezpiecznego wariantu tego hacka, spróbuj użyćtextarea
.Matthias Bynens ma bibliotekę do tego: https://github.com/mathiasbynens/he
Przykład:
Sugeruję faworyzowanie go w stosunku do hacków polegających na ustawianiu zawartości HTML elementu, a następnie ponownym przeczytaniu jego zawartości tekstowej. Takie podejścia mogą działać, ale są zwodniczo niebezpieczne i stwarzają możliwości XSS, jeśli są stosowane przy niezaufanym wkładzie użytkownika.
Jeśli naprawdę nie możesz znieść ładowania do biblioteki, możesz skorzystać z
textarea
hacka opisanego w tej odpowiedzi na prawie zduplikowane pytanie, które, w przeciwieństwie do różnych podobnych podejść, które zostały zasugerowane, nie ma dziur w zabezpieczeniach, o których wiem:Ale zwróć uwagę na kwestie bezpieczeństwa, wpływające na podobne podejścia do tego, które wymienię w powiązanej odpowiedzi! Takie podejście jest włamaniem, a przyszłe zmiany dopuszczalnej zawartości
textarea
(lub błędów w określonych przeglądarkach) mogą doprowadzić do tego, że kod, który się na niej opiera, nagle ma dziurę w XSS.źródło
he
jest absolutnie świetna! Dziękuję bardzo za rekomendację!Pochodzi z kodu źródłowego ExtJS.
źródło
htmlEnDecode.htmlDecode('€')
powinien zwrócić'€'
, ale zamiast tego zwraca'€'
.element.innerText
robi to samo.źródło
Możesz użyć funkcji Lodash unescape / escape https://lodash.com/docs/4.17.5#unescape
str stanie się
'fred, barney, & pebbles'
źródło
Jeśli tego szukasz, tak jak ja - tymczasem istnieje miła i bezpieczna metoda JQuery.
https://api.jquery.com/jquery.parsehtml/
Możesz np. wpisz to w konsoli:
Tak więc $ .parseHTML (x) zwraca tablicę, a jeśli masz znaczniki HTML w tekście, długość tablicy będzie większa niż 1.
źródło
x
ma wartość<script>alert('hello');</script>
powyższą, nastąpi awaria. W bieżącym jQuery tak naprawdę nie będzie próbował uruchomić skryptu, ale[0]
da wynik,undefined
więc wywołanietextContent
nie powiedzie się, a skrypt się na nim zatrzyma.$('<div />').html(x).text();
wygląda bezpieczniej - przez gist.github.com/jmblog/3222899jQuery koduje i dekoduje dla ciebie. Musisz jednak użyć tagu textarea, a nie div.
źródło
.html()
. Dlatego nawet użycietextarea
nie wystarcza do zapewnienia bezpieczeństwa; Sugeruję, aby nie używać jQuery do tego zadania i pisać równoważnego kodu za pomocą zwykłego API DOM . (Tak, to stare zachowanie jQuery jest szalone i okropne.)Najpierw stwórz
<span id="decodeIt" style="display:none;"></span>
gdzieś w cieleNastępnie przypisz ciąg do zdekodowania jako innerHTML do tego:
Wreszcie,
Oto ogólny kod:
źródło
stringtodecode
zawiera coś takiego<script>alert(1)</script>
.javascript, który łapie typowe:
jest to odwrotność https://stackoverflow.com/a/4835406/2738039
źródło
map[c] || ''
nierozpoznanych, nie będą wyświetlane jakoundefined
unescapeHtml(str){ var map = {amp: '&', lt: '<', le: '≤', gt: '>', ge: '≥', quot: '"', '#039': "'"} return str.replace(/&([^;]+);/g, (m, c) => map[c]|| '') }
Dla facetów z jednej linii:
źródło
Pytanie nie określa pochodzenia,
x
ale warto bronić, jeśli to możliwe, przed złośliwymi (lub po prostu nieoczekiwanymi przez naszą własną aplikację) danymi wejściowymi. Załóżmy na przykład, żex
ma wartość& <script>alert('hello');</script>
. Bezpiecznym i prostym sposobem radzenia sobie z tym w jQuery jest:Znaleziono za pośrednictwem https://gist.github.com/jmblog/3222899 . Nie widzę wielu powodów, aby unikać korzystania z tego rozwiązania, ponieważ jest ono co najmniej tak krótkie, jeśli nie krótsze niż niektóre alternatywy i zapewnia ochronę przed XSS.
(Pierwotnie zamieściłem to jako komentarz, ale dodaję to jako odpowiedź, ponieważ poprosił mnie o to kolejny komentarz w tym samym wątku).
źródło
Próbowałem wszystkiego, aby usunąć & z tablicy JSON. Żaden z powyższych przykładów, ale https://stackoverflow.com/users/2030321/chris dał świetne rozwiązanie, które doprowadziło mnie do rozwiązania mojego problemu.
Nie korzystałem, ponieważ nie rozumiałem, jak wstawić go do okna modalnego, które wciągało dane JSON do tablicy, ale spróbowałem tego na podstawie przykładu i zadziałało:
Podoba mi się, ponieważ był prosty i działa, ale nie jestem pewien, dlaczego nie jest szeroko stosowany. Szukano hi & low, aby znaleźć proste rozwiązanie. Nadal szukam zrozumienia tej składni i jeśli istnieje jakiekolwiek ryzyko z jej użyciem. Nic jeszcze nie znalazłem.
źródło