Как безопасно извлечь текстовое содержимое из произвольного HTML - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть какой-то пользовательский html, который я не могу контролировать;

Я хочу извлечь только текст (textContent, innerText, что угодно) из этого фрагмента html для отображения навеб-сайт.

Как можно безопасно получить текст, учитывая, что в этом html-содержании может содержаться вредоносный код, такой как теги скрипта, фреймы, теги стиля или другие подобные вещи.

Это пример ввода:

<p style="text-align:center;"><em>whatever</em></p>
<style>body { display: none } </style>

<p><em>Some more whatever</em></p>
<script>alert('lala')</script>

И это то, что я ожидаю обратно:

что угодно

еще что-нибудь

От чегоЯ понимаю, что решение не должно добавлять вещи в DOM, так как оно может потенциально увеличить вероятность атаки XSS.Использование белого / черного списков хорошо, но не идеально, потому что его сложно поддерживать (придумывать) и постоянно обновлять.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Вы можете использовать *:not() селектор, чтобы получить все элементы и исключить script элементы

const arbitraryHTML = `<p style="text-align:center;"><em>whatever</em></p>

<p><em>Some more whatever</em></p>
<script>alert('lala')<\/script>`;

function getTextFromHTML(arbitraryHTML){
  var a = document.createElement('div')
  a.innerHTML = arbitraryHTML;
  // exclude `script` elements at selector string
  return [...a.querySelectorAll('*:not(script)')]
         // filter nodes that do not have `firstElementChild`
         .filter(({firstElementChild})=> !firstElementChild)
         // return `textContent`
         .map(({textContent}) => textContent)
}

console.log(getTextFromHTML(arbitraryHTML))
0 голосов
/ 01 февраля 2019

Если вы используете свойство innerText вместо textContent, то содержимое любых тегов не будет возвращено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...