Стріпте HTML з текстового JavaScript


Відповіді:


761

Якщо ви працюєте в браузері, то найпростіший спосіб - просто дозволити веб-переглядачу зробити це за вас ...

function stripHtml(html)
{
   var tmp = document.createElement("DIV");
   tmp.innerHTML = html;
   return tmp.textContent || tmp.innerText || "";
}

Примітка: як люди зазначали у коментарях, цього найкраще уникати, якщо ви не керуєте джерелом HTML (наприклад, не запускайте це на тому, що могло б з’явитись із введення користувача). Для цих сценаріїв, ви можете все ще дозволити браузеру зробити роботу для вас - см відповіді Сабов на використання в даний час широко доступний DomParser .


40
Пам'ятайте лише, що такий підхід є досить непослідовним і не зможе позбавити певних символів у певних браузерах. Наприклад, у Prototype.js ми використовуємо такий підхід для продуктивності, але вирішуємо
kangax

11
Пам'ятайте, що ваш пробіл буде зіпсований. Я раніше використовував цей метод, а потім виникли проблеми, оскільки певні коди товарів містили подвійні пробіли, які закінчились як простіри після того, як я повернув внутрішній текст із DIV. Тоді коди продуктів не збігалися пізніше в додатку.
Магнус Сміт

11
@Magnus Smith: Так, якщо пробіл викликає занепокоєння - чи справді, якщо у вас є потреба в цьому тексті, який не стосується безпосередньо конкретного HTML DOM, з яким ви працюєте - тоді вам краще використовувати один з іншого рішення, наведені тут. Основні переваги цього методу полягають у тому, що він 1) тривіальний, і 2) надійно обробляє теги, пробіли, сутності, коментарі тощо так само, як і браузер, у якому ви працюєте . Це часто корисно для коду веб-клієнта, але не обов'язково підходить для взаємодії з іншими системами, де правила різні.
Shog9

220
Не використовуйте це з HTML з ненадійного джерела. Щоб зрозуміти, чому, спробуйте запуститиstrip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
Майк Самуель

24
Якщо html містить зображення (теги img), зображення запитає браузер. Це не добре.
douyw

589
myString.replace(/<[^>]*>?/gm, '');

4
Не працює, <img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)" якщо ви вводите ін'єкцію через document.writeабо об'єднуються з рядком, який містить >перед введенням через innerHTML.
Майк Самуель

1
@PerishableDave, я згоден, що >воля залишиться в другій. Однак це не є небезпечним для ін'єкцій. Небезпека виникає внаслідок <зліва в першій, що призводить до того, що HTML-аналізатор знаходиться в контексті, відмінному від стану даних, коли починається другий. Зауважте, що немає переходу від стану даних >.
Майк Самуель

73
@MikeSamuel Чи ми ще вирішили цю відповідь? Наївний користувач тут готовий скопіювати та вставити.
Ziggy

1
Це також, я вважаю, стає повністю заплутаним, якщо надавати щось на кшталт <button onClick="dostuff('>');"></button>Припустимо, правильно написаний HTML, ви все ще повинні враховувати, що більший, ніж знак, може бути десь у цитованому тексті атрибута. Також ви хочете <script>принаймні видалити весь текст всередині тегів.
Джонатан

15
@AntonioMax, я відповів на це питання з приводу нудоти , але на суть вашого запитання, оскільки критичний код безпеки не слід копіювати та вставляти. Вам слід завантажити бібліотеку та постійно оновлювати її та виправляти, щоб захиститись від нещодавно виявлених уразливостей та змін у веб-переглядачах.
Майк Самуель

249

Найпростіший спосіб:

jQuery(html).text();

Це витягує весь текст із рядка HTML.


111
Ми завжди використовуємо jQuery для проектів, оскільки незмінно у наших проектах багато Javascript. Тому ми не додавали об'єм, ми скористалися існуючим кодом API ...
Марк

32
Ви використовуєте його, але ОП може не зробити. питання стосувалося Javascript NOT JQuery.
Дементік

105
Це все ще корисна відповідь для людей, яким потрібно робити те саме, що і ОП (як я), і не проти використовувати jQuery (як я), не кажучи вже, це могло б бути корисним для ОП, якби вони розглядали можливість використання jQuery. Сенс сайту - обмін знаннями. Майте на увазі, що запаморочливий ефект, який ви можете мати, караючи корисні відповіді без поважних причин.
acjay

27
@Dementic шокуюче, я вважаю, що теми з декількома відповідями є найбільш корисними, оскільки часто вторинна відповідь відповідає моїм точним потребам, тоді як первинна відповідь відповідає загальному випадку.
Ерік Голдберг

36
Це не спрацює, якщо ви якась частина рядка не загорнута в html-тег. наприклад "<b> Помилка: </b> Будь ласка, введіть дійсну електронну пошту" повернеться лише "Помилка:"
Aamir Afridi

127

Я хотів би поділитися відредагованою версією схваленої відповіді Shog9 .


Як зауважив Майк Самуель із коментарем, ця функція може виконувати вбудовані коди JavaScript.
Але Shog9 має рацію, кажучи "нехай браузер зробить це за вас ..."

так .. ось моя відредагована версія за допомогою DOMParser :

function strip(html){
   var doc = new DOMParser().parseFromString(html, 'text/html');
   return doc.body.textContent || "";
}

тут код для перевірки вбудованого JavaScript:

strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")

Крім того, він не вимагає ресурсів для розбору (як зображення)

strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")

3
Варто додати, що це рішення працює лише в браузері.
kris_IV

1
Це не теги смужок, але більше схожі на PHP htmlspecialchars (). Ще корисна для мене.
Daantje

Зауважте, що це також видаляє пробіл з початку тексту.
Raine Revere

Також зауважимо, що це працює у веб-робочих
Кріс Сеферт

Це здається набагато швидшим, ніж відповідь @ Shog9
Шмуель Каменський

55

Як розширення до методу jQuery, якщо ваша рядок може не містити HTML (наприклад, якщо ви намагаєтесь видалити HTML з поля форми)

jQuery(html).text();`

поверне порожній рядок, якщо немає HTML

Використання:

jQuery('<p>' + html + '</p>').text();

замість цього.

Оновлення: Як було зазначено в коментарях, за деяких обставин це рішення виконуватиме JavaScript, який міститься в межах, htmlякщо на значення htmlмогло вплинути зловмисник, використовуйте інше рішення.


12
Або$("<p>").html(html).text();
Димитър Димитров

4
Це все ще виконує ймовірно небезпечний кодjQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
Саймон

спробуйте jQuery ("aa & # X003c; скрипт> попередження (1) & # X003c; / script> a"). text ();
Гжегож Качан

41

Перетворення HTML для простого тексту електронної пошти, зберігаючи гіперпосилання (href) недоторканими

Вищенаведена функція, розміщена гіпоксидом, працює чудово, але я працював над тим, що в основному перетворив би HTML, створений у веб-редакторі RichText (наприклад, FCKEditor) та очистив усі HTML, але залишив усі посилання через те, що я хотів і HTML, і звичайна текстова версія для сприяння створенню правильних частин для електронної пошти STMP (як HTML, так і простого тексту).

Після довгого пошуку в Google я та мої колеги придумали це за допомогою механізму regex у Javascript:

str='this string has <i>html</i> code i want to <b>remove</b><br>Link Number 1 -><a href="http://www.bbc.co.uk">BBC</a> Link Number 1<br><p>Now back to normal text and stuff</p>
';
str=str.replace(/<br>/gi, "\n");
str=str.replace(/<p.*>/gi, "\n");
str=str.replace(/<a.*href="(.*?)".*>(.*?)<\/a>/gi, " $2 (Link->$1) ");
str=str.replace(/<(?:.|\s)*?>/g, "");

strзмінна починається так:

this string has <i>html</i> code i want to <b>remove</b><br>Link Number 1 -><a href="http://www.bbc.co.uk">BBC</a> Link Number 1<br><p>Now back to normal text and stuff</p>

а потім після запуску коду виглядає приблизно так: -

this string has html code i want to remove
Link Number 1 -> BBC (Link->http://www.bbc.co.uk)  Link Number 1


Now back to normal text and stuff

Як ви бачите, всі HTML видалено, а посилання зберігається з текстом гіперпосилання. Також я замінив <p>і <br>теги на \n(char new line), щоб збереглося якесь візуальне форматування.

Щоб змінити формат посилання (напр. BBC (Link->http://www.bbc.co.uk)), Просто відредагуйте $2 (Link->$1), де $1є URL-адреса href / URI і the $2- гіперпосилання. З посиланнями безпосередньо в тексті простого тексту більшість клієнтів пошти SMTP перетворюють їх, щоб користувач мав можливість натискати на них.

Сподіваюся, ви вважаєте це корисним.


Він не обробляє "& nbsp;"
Роза Неттоєр

33

Поліпшення прийнятої відповіді.

function strip(html)
{
   var tmp = document.implementation.createHTMLDocument("New").body;
   tmp.innerHTML = html;
   return tmp.textContent || tmp.innerText || "";
}

Таким чином, щось подібне до цього не принесе шкоди:

strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")

Firefox, Chromium та Explorer 9+ безпечні. Opera Presto все ще вразлива. Також зображення, згадані в рядках, не завантажуються в Chromium та Firefox, зберігаючи http-запити.


Це є деякий шлях, але це не безпечно з<script><script>alert();
Арт

1
Тут не запускаються жодні сценарії в Chromium / Opera / Firefox в Linux, так чому це не безпечно?
Janghou

Вибачте, я, мабуть, пропустив тест, я, мабуть, забув натиснути запустити ще раз на jsFiddle.
Арт

Аргумент "Нового" - це зайве, я думаю?
Джон Шнайдер

Відповідно до специфікацій, це сьогодні необов'язково, але це було не завжди.
Janghou

23

Це повинно працювати в будь-якому середовищі Javascript (включений NodeJS).

const text = `
<html lang="en">
  <head>
    <style type="text/css">*{color:red}</style>
    <script>alert('hello')</script>
  </head>
  <body><b>This is some text</b><br/><body>
</html>`;

// Remove style tags and content
text.replace(/<style[^>]*>.*<\/style>/gm, '')
    // Remove script tags and content
    .replace(/<script[^>]*>.*<\/script>/gm, '')
    // Remove all opening, closing and orphan HTML tags
    .replace(/<[^>]+>/gm, '')
    // Remove leading spaces and repeated CR/LF
    .replace(/([\r\n]+ +)+/gm, '');

@pstanton Ви могли б надати робочий приклад своєї заяви?
Карл.S

3
<html><style..>* {font-family:comic-sans;}</style>Some Text</html>
pstanton

@pstanton Я виправив код і додав коментарі, вибачте за несвоєчасну відповідь.
Карл.S

15

Я змінив відповідь Jibberboy2000, щоб включити кілька <BR />форматів тегів, видалити все всередині <SCRIPT>та <STYLE>теги, відформатувати отриманий HTML, видаливши кілька розривів рядків та пробілів та перетворивши якийсь код, кодований HTML, у звичайний. Після деяких тестувань виявляється, що ви можете перетворити більшість повноцінних веб-сторінок у простий текст, де зберігаються заголовок сторінки та вміст.

У простому прикладі

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!--comment-->

<head>

<title>This is my title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>

    body {margin-top: 15px;}
    a { color: #D80C1F; font-weight:bold; text-decoration:none; }

</style>
</head>

<body>
    <center>
        This string has <i>html</i> code i want to <b>remove</b><br>
        In this line <a href="http://www.bbc.co.uk">BBC</a> with link is mentioned.<br/>Now back to &quot;normal text&quot; and stuff using &lt;html encoding&gt;                 
    </center>
</body>
</html>

стає

Це моя назва

Цей рядок має html-код, який я хочу видалити

У цьому рядку згадується BBC ( http://www.bbc.co.uk ) із посиланням.

Тепер повернемося до "звичайного тексту" та ін

Функція JavaScript та тестова сторінка виглядають так:

function convertHtmlToText() {
    var inputText = document.getElementById("input").value;
    var returnText = "" + inputText;

    //-- remove BR tags and replace them with line break
    returnText=returnText.replace(/<br>/gi, "\n");
    returnText=returnText.replace(/<br\s\/>/gi, "\n");
    returnText=returnText.replace(/<br\/>/gi, "\n");

    //-- remove P and A tags but preserve what's inside of them
    returnText=returnText.replace(/<p.*>/gi, "\n");
    returnText=returnText.replace(/<a.*href="(.*?)".*>(.*?)<\/a>/gi, " $2 ($1)");

    //-- remove all inside SCRIPT and STYLE tags
    returnText=returnText.replace(/<script.*>[\w\W]{1,}(.*?)[\w\W]{1,}<\/script>/gi, "");
    returnText=returnText.replace(/<style.*>[\w\W]{1,}(.*?)[\w\W]{1,}<\/style>/gi, "");
    //-- remove all else
    returnText=returnText.replace(/<(?:.|\s)*?>/g, "");

    //-- get rid of more than 2 multiple line breaks:
    returnText=returnText.replace(/(?:(?:\r\n|\r|\n)\s*){2,}/gim, "\n\n");

    //-- get rid of more than 2 spaces:
    returnText = returnText.replace(/ +(?= )/g,'');

    //-- get rid of html-encoded characters:
    returnText=returnText.replace(/&nbsp;/gi," ");
    returnText=returnText.replace(/&amp;/gi,"&");
    returnText=returnText.replace(/&quot;/gi,'"');
    returnText=returnText.replace(/&lt;/gi,'<');
    returnText=returnText.replace(/&gt;/gi,'>');

    //-- return
    document.getElementById("output").value = returnText;
}

Він використовувався з цим HTML:

<textarea id="input" style="width: 400px; height: 300px;"></textarea><br />
<button onclick="convertHtmlToText()">CONVERT</button><br />
<textarea id="output" style="width: 400px; height: 300px;"></textarea><br />

1
Мені подобається це рішення, оскільки воно має обробку спеціальних символів html ... але все ж їх недостатньо майже ... найкраща відповідь для мене стосується всіх них. (що, ймовірно, робить jquery).
Даніель Герсон

2
Я думаю, що /<p.*>/giмає бути /<p.*?>/gi.
cbron

Зверніть увагу , що для видалення всіх <br>тегів ви можете використовувати гарне регулярний вираз замість цього: /<br\s*\/?>/таким чином у вас є тільки один замінити замість 3. Крім того, мені здається , що для декодування осіб , за винятком ви можете мати один регулярний вираз, що - щось на зразок цього: /<[a-z].*?\/?>/.
Алексіс Вільке

Гарний сценарій. А як щодо вмісту таблиці? Будь-яка ідея, як її можна відобразити
Христо Єнев

@DanielGerson, кодування HTML стає реально волохатою, реально швидкою, але найкращим підходом здається використання бібліотеки він
KyleMit

15
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");

Це версія регулярної виразки, яка є більш стійкою до неправильного HTML, наприклад:

Незакриті теги

Some text <img

"<", ">" внутрішні атрибути тегу

Some text <img alt="x > y">

Нові рядки

Some <a href="http://google.com">

Код

var html = '<br>This <img alt="a>b" \r\n src="a_b.gif" />is > \nmy<>< > <a>"text"</a'
var text = html.replace(/<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g, "");

7

Іншим, правда, менш елегантним рішенням, ніж Nickf's або Shog9, було б рекурсивно ходити по DOM, починаючи з тегу <body> і додавати кожен текстовий вузол.

var bodyContent = document.getElementsByTagName('body')[0];
var result = appendTextNodes(bodyContent);

function appendTextNodes(element) {
    var text = '';

    // Loop through the childNodes of the passed in element
    for (var i = 0, len = element.childNodes.length; i < len; i++) {
        // Get a reference to the current child
        var node = element.childNodes[i];
        // Append the node's value if it's a text node
        if (node.nodeType == 3) {
            text += node.nodeValue;
        }
        // Recurse through the node's children, if there are any
        if (node.childNodes.length > 0) {
            appendTextNodes(node);
        }
    }
    // Return the final result
    return text;
}

3
поступається. якщо ви збираєтеся створити дерево DOM зі своєї рядка, просто використовуйте шлях шога!
nickf

Так, у моєму рішенні є кувалда, де правильніший молоток є більш відповідним :-). І я погоджуюся, що ваші рішення та рішення Shog9 кращі, і в основному сказано стільки ж у відповіді. Я також не зміг відобразити у своїй відповіді, що html вже міститься в рядку, що робить мою відповідь в основному марною щодо оригінального запитання. :-(
Брайан

1
Якщо чесно, це має значення - якщо ви абсолютно повинні зберегти / all / тексту, то це має принаймні гідний знімок у захопленні нових рядків, вкладок, повернень перевезення тощо ... Потім знову, рішення Nickf має зробити те саме , і робити набагато швидше ... ах.
Shog9

7

Якщо ви хочете зберегти посилання та структуру вмісту (h1, h2 тощо), то слід перевірити TextVersionJS Ви можете використовувати його з будь-яким HTML, хоча він був створений для перетворення електронної пошти HTML у звичайний текст.

Використання дуже просте. Наприклад у node.js:

var createTextVersion = require("textversionjs");
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";

var textVersion = createTextVersion(yourHtml);

Або в браузері з чистим js:

<script src="textversion.js"></script>
<script>
  var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
  var textVersion = createTextVersion(yourHtml);
</script>

Він також працює з Requ.js:

define(["textversionjs"], function(createTextVersion) {
  var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
  var textVersion = createTextVersion(yourHtml);
});

4

Спробувавши всі відповіді, згадані більшість, якщо не всі вони мали кращі справи і не змогли повністю підтримати мої потреби.

Я почав досліджувати, як це робить php, і натрапив на php.js lib, який повторює метод strip_tags тут: http://phpjs.org/functions/strip_tags/


Це акуратна функція і добре задокументована. Однак це може бути зроблено швидше, коли, allowed == ''я думаю, це те, про що просив ОП, а це майже те, що Байрон відповів нижче (Байрон тільки [^>]помилився.)
Алексіс Вілке

1
Якщо ви використовуєте allowedпарам, ви вразливі до XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')повертається<p onclick="alert(1)">mytext</p>
Кріс Сінеллі,

4
function stripHTML(my_string){
    var charArr   = my_string.split(''),
        resultArr = [],
        htmlZone  = 0,
        quoteZone = 0;
    for( x=0; x < charArr.length; x++ ){
     switch( charArr[x] + htmlZone + quoteZone ){
       case "<00" : htmlZone  = 1;break;
       case ">10" : htmlZone  = 0;resultArr.push(' ');break;
       case '"10' : quoteZone = 1;break;
       case "'10" : quoteZone = 2;break;
       case '"11' : 
       case "'12" : quoteZone = 0;break;
       default    : if(!htmlZone){ resultArr.push(charArr[x]); }
     }
    }
    return resultArr.join('');
}

Обліковий запис> внутрішніх атрибутів та <img onerror="javascript">в новостворених елементах dom.

використання:

clean_string = stripHTML("string with <html> in it")

демонстрація:

https://jsfiddle.net/gaby_de_wilde/pqayphzd/

демонстрація топ-відповіді, що робить жахливі речі:

https://jsfiddle.net/gaby_de_wilde/6f0jymL6/1/


Вам також доведеться обробляти пропущені лапки всередині значення атрибута (наприклад string with <a malicious="attribute \">this text should be removed, but is not">example</a>).
Логан Пікап

4

Багато людей вже відповіли на це, але я вважав, що може бути корисним поділитися функцією, яку я написав, що знімає HTML-теги з рядка, але дозволяє включити масив тегів, які ви не хочете позбавляти. Це досить коротко і добре працює для мене.

function removeTags(string, array){
  return array ? string.split("<").filter(function(val){ return f(array, val); }).map(function(val){ return f(array, val); }).join("") : string.split("<").map(function(d){ return d.split(">").pop(); }).join("");
  function f(array, value){
    return array.map(function(d){ return value.includes(d + ">"); }).indexOf(true) != -1 ? "<" + value : value.split(">")[1];
  }
}

var x = "<span><i>Hello</i> <b>world</b>!</span>";
console.log(removeTags(x)); // Hello world!
console.log(removeTags(x, ["span", "i"])); // <span><i>Hello</i> world!</span>

3

Я думаю, що найпростіший спосіб - просто використовувати регулярні вирази, як хтось згаданий вище. Хоча немає жодної причини використовувати купу з них. Спробуйте:

stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");

11
Не робіть цього, якщо ви дбаєте про безпеку. Якщо введення користувача таке: '<scr <script> ipt> попередження (42); </ scr </script> ipt>', тоді позбавлена ​​версія буде такою: '<script> попередження (42); </ script > '. Отже, це вразливість XSS.
molnarg

Ви повинні змінити [^<>]з , [^>]оскільки дійсний тег не може містити <символ, то вразливість XSS зникає.
Алексіс Вільке

3

Я вніс деякі зміни в оригінальний сценарій Jibberboy2000 Сподіваюся, що це буде корисним для когось

str = '**ANY HTML CONTENT HERE**';

str=str.replace(/<\s*br\/*>/gi, "\n");
str=str.replace(/<\s*a.*href="(.*?)".*>(.*?)<\/a>/gi, " $2 (Link->$1) ");
str=str.replace(/<\s*\/*.+?>/ig, "\n");
str=str.replace(/ {2,}/gi, " ");
str=str.replace(/\n+\s*/gi, "\n\n");

3

Ось версія, яка сортує адресу @ MikeSamuel з питань безпеки:

function strip(html)
{
   try {
       var doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
       doc.documentElement.innerHTML = html;
       return doc.documentElement.textContent||doc.documentElement.innerText;
   } catch(e) {
       return "";
   }
}

Зауважте, він поверне порожній рядок, якщо розмітка HTML не є дійсною XML (він же має бути закритий, а атрибути повинні бути цитовані). Це не ідеально, але це дозволяє уникати можливості використання потенціалу безпеки.

Якщо для вас не є дійсна розмітка XML, ви можете спробувати скористатися:

var doc = document.implementation.createHTMLDocument("");

але це не ідеальне рішення ні з інших причин.


Це не вдасться за багатьох обставин, якщо текст надходить із введення користувачем (textarea або widtentable widget ...)
Alexis Wilke

3

Ви можете сміливо знімати HTML-теги за допомогою атрибуту iframe sandbox .

Ідея тут полягає в тому, що замість того, щоб намагатися повторно виразити наш рядок, ми скористаємось нативним аналізатором браузера, вводячи текст у елемент DOM, а потім запитуючи textContent/ innerTextвластивість цього елемента.

Найкращим елементом, в який потрібно вставити наш текст, є пісочний кадр, тому ми можемо запобігти будь-якому довільному виконанню коду (Також відомому як XSS ).

Мінусом такого підходу є те, що він працює лише в браузерах.

Ось що я придумав (Не перевірений боєм):

const stripHtmlTags = (() => {
  const sandbox = document.createElement("iframe");
  sandbox.sandbox = "allow-same-origin"; // <--- This is the key
  sandbox.style.setProperty("display", "none", "important");

  // Inject the sanbox in the current document
  document.body.appendChild(sandbox);

  // Get the sandbox's context
  const sanboxContext = sandbox.contentWindow.document;

  return (untrustedString) => {
    if (typeof untrustedString !== "string") return ""; 

    // Write the untrusted string in the iframe's body
    sanboxContext.open();
    sanboxContext.write(untrustedString);
    sanboxContext.close();

    // Get the string without html
    return sanboxContext.body.textContent || sanboxContext.body.innerText || "";
  };
})();

Використання ( демонстрація ):

console.log(stripHtmlTags(`<img onerror='alert("could run arbitrary JS here")' src='bogus'>XSS injection :)`));
console.log(stripHtmlTags(`<script>alert("awdawd");</` + `script>Script tag injection :)`));
console.log(stripHtmlTags(`<strong>I am bold text</strong>`));
console.log(stripHtmlTags(`<html>I'm a HTML tag</html>`));
console.log(stripHtmlTags(`<body>I'm a body tag</body>`));
console.log(stripHtmlTags(`<head>I'm a head tag</head>`));
console.log(stripHtmlTags(null));

Чудове рішення для веб-середовищ! Ви, ймовірно, не повинні використовувати IIFE, оскільки з ECMAScript 2015 змінні, що охоплюють блок, вже належним чином передаються до блоку разом із операторами letта const. Також, використовуючи ваше рішення, я отримав багато посилань на iframesне використовувані всередині документа. Подумайте про додавання document.body.removeChild(sandbox)коду для майбутніх читачів на основі копій-макаронних виробів.
Амін

2

За допомогою jQuery ви можете просто отримати його за допомогою

$('#elementID').text()

2

Нижче код дозволяє зберігати деякі теги html, знімаючи всі інші

function strip_tags(input, allowed) {

  allowed = (((allowed || '') + '')
    .toLowerCase()
    .match(/<[a-z][a-z0-9]*>/g) || [])
    .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)

  var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
      commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;

  return input.replace(commentsAndPhpTags, '')
      .replace(tags, function($0, $1) {
          return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
      });
}

1
Вам слід вказати джерело ( phpjs). Якщо ви використовуєте allowedпарам, ви вразливі до XSS: stripTags('<p onclick="alert(1)">mytext</p>', '<p>')повертається<p onclick="alert(1)">mytext</p>
Кріс Сінеллі,

2

Можна також використовувати фантастичний htserparser2 чистий JS HTML-аналізатор. Ось робоча демонстрація:

var htmlparser = require('htmlparser2');

var body = '<p><div>This is </div>a <span>simple </span> <img src="test"></img>example.</p>';

var result = [];

var parser = new htmlparser.Parser({
    ontext: function(text){
        result.push(text);
    }
}, {decodeEntities: true});

parser.write(body);
parser.end();

result.join('');

Вихід буде This is a simple example.

Побачити це в дії тут: https://tonicdev.com/jfahrenkrug/extract-text-from-html

Це працює як у вузлі, так і в браузері, якщо ви пакуєте веб-додаток за допомогою такого інструменту, як webpack.


2

Мені просто потрібно було викреслити <a>теги і замінити їх текстом посилання.

Це, здається, працює чудово.

htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');

Це стосується лише тегів і потребує налаштування для широкої функції.
м3нда

Так, плюс тег якір може мати багато інших атрибутів, таких як title="...".
Алексіс Вільке


1

Я сам створив робочий регулярний вираз:

str=str.replace(/(<\?[a-z]*(\s[^>]*)?\?(>|$)|<!\[[a-z]*\[|\]\]>|<!DOCTYPE[^>]*?(>|$)|<!--[\s\S]*?(-->|$)|<[a-z?!\/]([a-z0-9_:.])*(\s[^>]*)?(>|$))/gi, ''); 

1

простий дворядковий jquery, щоб зняти HTML.

 var content = "<p>checking the html source&nbsp;</p><p>&nbsp;
  </p><p>with&nbsp;</p><p>all</p><p>the html&nbsp;</p><p>content</p>";

 var text = $(content).text();//It gets you the plain text
 console.log(text);//check the data in your console

 cj("#text_area_id").val(text);//set your content to text area using text_area_id

1

Прийнята відповідь здебільшого добре працює, проте в IE, якщо htmlрядок nullви отримаєте "null"(замість ''). Виправлено:

function strip(html)
{
   if (html == null) return "";
   var tmp = document.createElement("DIV");
   tmp.innerHTML = html;
   return tmp.textContent || tmp.innerText || "";
}


1

inputелемент підтримує лише один текст рядка :

Стан тексту являє собою однорядковий елемент редагування тексту для значення елемента.

function stripHtml(str) {
  var tmp = document.createElement('input');
  tmp.value = str;
  return tmp.value;
}

Оновлення: це працює як очікувалося

function stripHtml(str) {
  // Remove some tags
  str = str.replace(/<[^>]+>/gim, '');

  // Remove BB code
  str = str.replace(/\[(\w+)[^\]]*](.*?)\[\/\1]/g, '$2 ');

  // Remove html and line breaks
  const div = document.createElement('div');
  div.innerHTML = str;

  const input = document.createElement('input');
  input.value = div.textContent || div.innerText || '';

  return input.value;
}

Не працює, будь-коли вказуйте браузер, який ви використовуєте, коли публікуєте відповідь. Це неточно і не працює в Chrome 61. Теги відображаються просто як рядок.
вдегенне

0
    (function($){
        $.html2text = function(html) {
            if($('#scratch_pad').length === 0) {
                $('<div id="lh_scratch"></div>').appendTo('body');  
            }
            return $('#scratch_pad').html(html).text();
        };

    })(jQuery);

Визначте це як плагін jquery і використовуйте його так:

$.html2text(htmlContent);

Скажімо, це відбувається від введення користувача. З його допомогою можна додати скрипт або макроси на вашу сторінку
Oluwatumbi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.