Mam kod JavaScript, który komunikuje się z zapleczem XML-RPC. XML-RPC zwraca ciągi w postaci:
<img src='myimage.jpg'>
Jednak kiedy używam JavaScript do wstawiania ciągów do HTML, renderują się one dosłownie. Nie widzę obrazu, dosłownie widzę ciąg:
<img src='myimage.jpg'>
Domyślam się, że kod HTML jest usuwany przez kanał XML-RPC.
Jak mogę usunąć ciąg znaków w Javascript? Wypróbowałem techniki na tej stronie, bezskutecznie: http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/
Jakie są inne sposoby zdiagnozowania problemu?
javascript
html
escaping
xml-rpc
Józefa Turiana
źródło
źródło
Odpowiedzi:
EDYCJA: Powinieneś używać DOMParser API, jak sugeruje Wladimir. Edytowałem moją poprzednią odpowiedź, ponieważ opublikowana funkcja wprowadziła lukę w zabezpieczeniach.
Poniższy fragment to kod starej odpowiedzi z niewielką modyfikacją: użycie a
textarea
zamiast adiv
zmniejsza podatność na XSS, ale nadal jest problematyczne w IE9 i Firefox.Zasadniczo tworzę programowo element DOM, przypisuję zakodowany kod HTML do jego innerHTML i pobieram wartość nodeValue z węzła tekstowego utworzonego przy wstawieniu innerHTML. Ponieważ po prostu tworzy element, ale nigdy go nie dodaje, żaden kod HTML witryny nie jest modyfikowany.
Będzie działać na różnych przeglądarkach (w tym starszych przeglądarkach) i akceptować wszystkie jednostki znaków HTML .
EDYCJA: Stara wersja tego kodu nie działała w IE z pustymi danymi wejściowymi, jak pokazano tutaj na jsFiddle (widok w IE). Powyższa wersja działa ze wszystkimi wejściami.
AKTUALIZACJA: wygląda na to, że nie działa to z dużym ciągiem znaków, a także wprowadza lukę w zabezpieczeniach , patrz komentarze.
źródło
'
nie należy do HTML 4 Entities, dlatego! w3.org/TR/html4/sgml/entities.html fishbowl.pastiche.org/2003/07/01/the_curse_of_aposWiększość udzielonych tutaj odpowiedzi ma ogromną wadę: jeśli ciąg, który próbujesz przekonwertować, nie jest zaufany, otrzymasz lukę w zabezpieczeniach Cross-Site Scripting (XSS) . W przypadku funkcji w zaakceptowanej odpowiedzi rozważ następujące kwestie:
Łańcuch zawiera tutaj znacznik HTML bez zmiany znaczenia, więc zamiast dekodowania czegokolwiek
htmlDecode
funkcja w rzeczywistości uruchomi kod JavaScript określony w ciągu.Można tego uniknąć, używając DOMParser, który jest obsługiwany we wszystkich nowoczesnych przeglądarkach :
Ta funkcja gwarantuje, że jako efekt uboczny nie uruchomi się żadnego kodu JavaScript. Wszelkie tagi HTML zostaną zignorowane, zwrócona zostanie tylko treść tekstowa.
Uwaga dotycząca zgodności : parsowanie HTML z
DOMParser
wymaga co najmniej Chrome 30, Firefox 12, Opera 17, Internet Explorer 10, Safari 7.1 lub Microsoft Edge. Tak więc wszystkie przeglądarki bez wsparcia są daleko poza ich EOL, a od 2017 roku jedynymi, które wciąż można zobaczyć na wolności, są starsze wersje Internet Explorera i Safari (zwykle nie są one wystarczająco liczne, aby przeszkadzać).źródło
DOMParser
nie obsługiwał"text/html"
przeglądarki Firefox przed wersjąDOMParser.prototype.parseFromString()
12.0 i nadal istnieją najnowsze wersje przeglądarek, które nawet nie obsługują . Zgodnie z twoją referencją,DOMParser
jest to wciąż technologia eksperymentalna, a stand-iny wykorzystująinnerHTML
właściwość, która, jak również wskazałeś w odpowiedzi na moje podejście , ma tę lukę w zabezpieczeniach XSS (która powinna zostać naprawiona przez dostawców przeglądarek).<script>
tagi, które nie są wykonywane, nie są mechanizmem bezpieczeństwa, ta reguła po prostu pozwala uniknąć skomplikowanych problemów z synchronizacją, jeśli ustawienieinnerHTML
mogłoby spowodować uruchomienie synchronicznych skryptów jako efekt uboczny. Oczyszczanie kodu HTML jest trudną sprawą iinnerHTML
nawet nie próbuje - już dlatego, że strona internetowa może faktycznie zamierzać ustawić wbudowane programy obsługi zdarzeń. To po prostu nie jest mechanizm przeznaczony do niebezpiecznych danych, kropka.Jeśli używasz jQuery:
W przeciwnym razie użyj obiektu enkodera Strictly Software , który ma doskonałą
htmlDecode()
funkcję.źródło
Sztuczka polega na wykorzystaniu mocy przeglądarki do dekodowania specjalnych znaków HTML, ale nie pozwala przeglądarce na wykonanie wyników tak, jakby to był rzeczywisty html ... Ta funkcja używa wyrażenia regularnego do identyfikacji i zamiany zakodowanych znaków HTML, jeden znak na czas.
źródło
/\&#?[0-9a-z]+;/gi
ponieważ # powinno pojawiać się tylko jako drugi znak, jeśli w ogóle.Odpowiedź CMS działa dobrze, chyba że kod HTML, który chcesz usunąć, jest bardzo długi, dłuższy niż 65536 znaków. Ponieważ wtedy w Chrome wewnętrzny kod HTML zostaje podzielony na wiele węzłów podrzędnych, z których każdy ma maksymalnie 65536 długości i trzeba je połączyć. Ta funkcja działa również dla bardzo długich ciągów:
Zobacz tę odpowiedź na temat
innerHTML
maksymalnej długości, aby uzyskać więcej informacji: https://stackoverflow.com/a/27545633/694469źródło
Nie jest to bezpośrednia odpowiedź na twoje pytanie, ale czy nie byłoby lepiej, gdyby RPC zwrócił jakąś strukturę (czy to XML, JSON czy cokolwiek innego) z tymi danymi obrazu (adresy URL w twoim przykładzie) wewnątrz tej struktury?
Następnie możesz po prostu przeanalizować go w swoim javascript i zbudować za
<img>
pomocą samego javascript.Struktura otrzymana od RPC może wyglądać następująco:
Myślę, że tak jest lepiej, ponieważ wstrzyknięcie kodu pochodzącego z zewnętrznego źródła na twoją stronę nie wygląda na zbyt bezpieczne. Wyobrażanie sobie kogoś, kto porywa twój skrypt XML-RPC i umieszcza w nim coś, czego nie chcesz (nawet javascript ...)
źródło
htmlDecode("<img src='myimage.jpg'><script>alert('xxxxx');</script>")
i nic się nie stało. Otrzymałem z powrotem zdekodowany ciąg html zgodnie z oczekiwaniami.Odpowiedź Chrisa jest ładna i elegancka, ale zawodzi, jeśli wartość jest nieokreślona . Wystarczy prosta poprawa, aby było solidne:
źródło
return (typeof value !== 'string') ? '' : $('<div/>').html(value).text();
Nie ma za co ... po prostu posłaniec ... pełne uznanie trafia do ourcodeworld.com, link poniżej.
Pełny kredyt: https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript
źródło
To najbardziej kompleksowe rozwiązanie, jakie do tej pory wypróbowałem:
źródło
Byłem na tyle szalony, aby przejść przez tę funkcję, która powinna być ładna, jeśli nie całkowicie, wyczerpująca:
Używane tak:
Wydruki:
Ich Heiße David
PS to zajęło półtorej godziny.
źródło
Aby usunąć elementy HTML * w JavaScript, możesz użyć małej biblioteki html-escaper :
npm install html-escaper
Lub działaj
unescape
z Lodash lub Underscore , jeśli go używasz.*) Należy pamiętać, że funkcje te nie obejmują wszystkie podmioty HTML, ale tylko najbardziej popularne, czyli
&
,<
,>
,'
,"
. O przywróceniu znaczenia wszystkie podmioty HTML można użyć he bibliotekę.źródło
Używam tego w moim projekcie: zainspirowany innymi odpowiedziami, ale z dodatkowym bezpiecznym parametrem, może być przydatny, gdy masz do czynienia z dekorowanymi postaciami
I to jest użyteczne jak:
źródło
Wszystkie inne odpowiedzi tutaj mają problemy.
Metody document.createElement ('div') (w tym te używające jQuery) wykonują każdy przekazany do nich kod javascript (kwestia bezpieczeństwa), a metoda DOMParser.parseFromString () przycina białe znaki. Oto czyste rozwiązanie javascript, które nie ma żadnego problemu:
TextArea jest używana specjalnie w celu uniknięcia wykonywania kodu js. Przechodzi te:
źródło
htmlDecode("</textarea><img src=x onerror=alert(1)>")
. Opublikowałeś to po tym, jak już wskazałem tę kwestię w odpowiedzi Sergio Belevskij.źródło
Istnieje wariant, który w 80% jest tak produktywny, jak odpowiedzi na samej górze.
Zobacz test porównawczy: https://jsperf.com/decode-html12345678/1
Jeśli chcesz zostawić tagi, usuń dwa
.replace(...)
wywołania (możesz zostawić pierwsze, jeśli nie potrzebujesz skryptów).źródło
decodeEntities("</textarea '><img src=x onerror=alert(1) \">")
w przeglądarce Firefox. Przestań próbować oczyścić kod HTML za pomocą wyrażeń regularnych.