У меня есть некоторый код Javascript, который взаимодействует с бэкэндом XML-RPC. XML-RPC возвращает строки в форме:
<img src='myimage.jpg'>
Однако когда я использую Javascript для вставки строк в HTML, они отображаются буквально. Я не вижу изображения, я буквально вижу строку:
<img src='myimage.jpg'>
Я предполагаю, что HTML экранируется по каналу XML-RPC.
Как я могу удалить строку в Javascript? Я попробовал методы на этой странице, но безуспешно: http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/
Каковы другие способы диагностики проблемы?
javascript
html
escaping
xml-rpc
Иосиф Туриан
источник
источник
Ответы:
РЕДАКТИРОВАТЬ: Вы должны использовать API DOMParser, как подсказывает Владимир , я отредактировал свой предыдущий ответ, так как опубликованная функция представила уязвимость безопасности.
Следующий фрагмент кода старого ответа с небольшой модификацией: использование
textarea
вместо вместоdiv
уменьшает уязвимость XSS, но все еще проблематично в IE9 и Firefox.По сути, я создаю элемент DOM программно, назначаю закодированный HTML-код его innerHTML и извлекаю nodeValue из текстового узла, созданного при вставке innerHTML. Поскольку он просто создает элемент, но никогда не добавляет его, HTML-код сайта не изменяется.
Он будет работать в кросс-браузерном режиме (включая старые браузеры) и принимать все объекты символов HTML .
РЕДАКТИРОВАТЬ: старая версия этого кода не работала на IE с пустыми вводами , как показано здесь на jsFiddle (просмотр в IE). Версия выше работает со всеми входами.
ОБНОВЛЕНИЕ: кажется, это не работает с большой строкой, и это также представляет уязвимость безопасности , см. Комментарии.
источник
'
не принадлежит сущностям HTML 4, вот почему! w3.org/TR/html4/sgml/entities.html fishbowl.pastiche.org/2003/07/01/the_curse_of_aposБольшинство ответов, приведенных здесь, имеют огромный недостаток: если строка, которую вы пытаетесь преобразовать, не является доверенной, в результате вы получите уязвимость для межсайтового скриптинга (XSS) . Для функции в принятом ответе учтите следующее:
Здесь строка содержит неэкранированный HTML-тег, поэтому вместо расшифровки чего-либо
htmlDecode
функция на самом деле будет выполнять код JavaScript, указанный внутри строки.Этого можно избежать, используя DOMParser, который поддерживается во всех современных браузерах :
Эта функция гарантированно не запускает какой-либо код JavaScript в качестве побочного эффекта. Любые HTML-теги будут игнорироваться, будет возвращен только текстовый контент.
Примечание о совместимости : для анализа HTML
DOMParser
требуется как минимум Chrome 30, Firefox 12, Opera 17, Internet Explorer 10, Safari 7.1 или Microsoft Edge. Таким образом, все браузеры без поддержки уже прошли EOL, и по состоянию на 2017 год единственными, которые все еще можно увидеть в дикой природе, иногда являются старые версии Internet Explorer и Safari (обычно их все еще недостаточно, чтобы беспокоиться).источник
DOMParser
не поддерживал"text/html"
до Firefox 12.0, и все еще есть некоторые последние версии браузеров, которые даже не поддерживаютDOMParser.prototype.parseFromString()
. Согласно вашему упоминанию,DOMParser
это все еще экспериментальная технология, и в ней используютсяinnerHTML
свойства, которые, как вы также указали в ответ на мой подход , имеют эту уязвимость XSS (которую должны исправлять производители браузеров).<script>
теги, которые не выполняются, не являются механизмом безопасности, это правило просто исключает сложные временные проблемы, если настройкаinnerHTML
может запускать синхронные сценарии как побочный эффект. Санитарная обработка HTML-кода - дело сложное иinnerHTML
даже не пытается - уже потому, что на веб-странице могут быть заданы встроенные обработчики событий. Это просто не механизм, предназначенный для небезопасных данных, полная остановка.Если вы используете jQuery:
В противном случае используйте объект кодирования Strictly Software , который имеет отличную
htmlDecode()
функцию.источник
Хитрость заключается в том, чтобы использовать возможности браузера для декодирования специальных символов HTML, но не позволять браузеру выполнять результаты, как если бы это был настоящий HTML ... Эта функция использует регулярное выражение для идентификации и замены закодированных символов HTML, одного символа вовремя.
источник
/\&#?[0-9a-z]+;/gi
так как # должно появляться только как 2-й символ, если он вообще есть.Ответ CMS работает нормально, если только HTML-код, который вы хотите удалить, не очень длинный, длиннее 65536 символов. Потому что тогда в Chrome внутренний HTML разбивается на множество дочерних узлов, каждый длиной не более 65536, и вам нужно объединить их. Эта функция работает также для очень длинных строк:
См. Этот ответ о
innerHTML
максимальной длине для получения дополнительной информации: https://stackoverflow.com/a/27545633/694469источник
Не прямой ответ на ваш вопрос, но не лучше ли для вашего RPC вернуть некоторую структуру (будь то XML, JSON или что-то еще) с этими данными изображения (URL в вашем примере) внутри этой структуры?
Затем вы можете просто проанализировать его в своем javascript и создать сам
<img>
JavaScript.Структура, которую вы получаете от RPC, может выглядеть так:
Я думаю, что так будет лучше, поскольку внедрение кода, полученного из внешнего источника, на вашу страницу не выглядит очень безопасным. Представьте, что кто-то захватывает ваш XML-RPC-скрипт и помещает туда что-то, что вам не нужно (даже некоторый javascript ...)
источник
htmlDecode("<img src='myimage.jpg'><script>alert('xxxxx');</script>")
и ничего не случилось. Я получил декодированную строку HTML обратно, как и ожидалось.Крис ответ хороший и элегантный , но оно не выполняется , если значение не определено . Просто простое улучшение делает это твердым:
источник
return (typeof value !== 'string') ? '' : $('<div/>').html(value).text();
Не за что ... просто посыльный ... полный кредит переходит на ourcodeworld.com, ссылка ниже.
Полный кредит: https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript
источник
Это наиболее полное решение, которое я пробовал до сих пор:
источник
Я был достаточно сумасшедшим, чтобы пройти и сделать эту функцию, которая должна быть довольно, если не полностью, исчерпывающей:
Используется так:
Печать:
Ich Heiße David
PS это заняло как полтора часа, чтобы сделать.
источник
Чтобы скрыть HTML-сущности * в JavaScript, вы можете использовать небольшую библиотеку html-escaper :
npm install html-escaper
Или используйте
unescape
функцию Lodash или Underscore , если вы ее используете.*) Пожалуйста , обратите внимание , что эти функции не охватывают всех HTML сущностей, но только самые распространенные из них, то есть
&
,<
,>
,'
,"
. Для того, чтобы все HTML экранирования в сущности вы можете использовать он библиотеку.источник
Я использую это в своем проекте: вдохновленный другими ответами, но с дополнительным безопасным параметром, может быть полезен, когда вы имеете дело с украшенными персонажами
И это можно использовать как:
источник
Все остальные ответы здесь имеют проблемы.
Методы document.createElement ('div') (включая методы, использующие jQuery) выполняют любой переданный в него javascript (проблема безопасности), а метод DOMParser.parseFromString () удаляет пробелы. Вот чистое решение JavaScript, которое не имеет ни одной проблемы:
TextArea используется специально, чтобы избежать выполнения кода JS. Это проходит эти:
источник
htmlDecode("</textarea><img src=x onerror=alert(1)>")
. Вы опубликовали это после того, как я уже указал на этот вопрос в ответе Серхио Белевского.источник
Есть вариант, который на 80% продуктивнее ответов на самом верху.
См. Тест: https://jsperf.com/decode-html12345678/1
Если вам нужно оставить теги, удалите два
.replace(...)
вызова (вы можете оставить первый, если вам не нужны скрипты).источник
decodeEntities("</textarea '><img src=x onerror=alert(1) \">")
в Firefox. Пожалуйста, прекратите попытки дезинфицировать HTML-код с помощью регулярных выражений.