답변:
브라우저에서 실행중인 경우 가장 쉬운 방법은 브라우저가 브라우저 를 대신 하도록하는 것입니다 ...
function stripHtml(html)
{
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
참고 : 사람들이 주석에서 언급했듯이 HTML 소스를 제어하지 않으면 (예를 들어 사용자 입력에서 얻을 수있는 것에서 실행하지 마십시오) 피하는 것이 가장 좋습니다. 이러한 시나리오의 경우 에도 브라우저에서 작업을 수행 할 수 있습니다 . 현재 널리 사용되는 DOMParser 사용에 대한 Saba의 답변을 참조하십시오 .
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
myString.replace(/<[^>]*>?/gm, '');
<img src=http://www.google.com.kh/images/srpr/nav_logo27.png onload="alert(42)"
via를 주입 document.write
하거나 >
via를 주입하기 전에 를 포함하는 문자열과 연결 하는 경우 에는 작동하지 않습니다 innerHTML
.
>
두 번째에 남을 것에 동의합니다 . 그것은 주입 위험이 아닙니다. <
첫 번째 문자가 왼쪽 으로 인해 위험이 발생 하여 두 번째 시작시 HTML 구문 분석기가 데이터 상태 이외의 컨텍스트에있게 됩니다. 에 데이터 상태에서 전환이 없습니다 >
.
<button onClick="dostuff('>');"></button>
올바르게 작성된 HTML이라고 가정하는 경우 속성의 인용 된 텍스트 어딘가보다 큰 기호가있을 수 있다는 점을 고려해야합니다. 또한 <script>
적어도 태그 안의 모든 텍스트를 제거하고 싶을 것 입니다.
가장 간단한 방법 :
jQuery(html).text();
html 문자열에서 모든 텍스트를 검색합니다.
Shog9 의 승인 된 답변의 편집 된 버전을 공유하고 싶습니다 .
Mike Samuel 이 주석으로 지적한 것처럼 이 함수는 인라인 자바 스크립트 코드를 실행할 수 있습니다.
그러나 Shog9 "브라우저가 대신 해줄 것"이라고 말할 때 가 옳습니다.
그래서 .. 여기 DOMParser를 사용하여 편집 한 버전 :
function strip(html){
var doc = new DOMParser().parseFromString(html, 'text/html');
return doc.body.textContent || "";
}
다음은 인라인 자바 스크립트를 테스트하는 코드입니다.
strip("<img onerror='alert(\"could run arbitrary JS here\")' src=bogus>")
또한 이미지와 같은 구문 분석에 대한 리소스를 요청하지 않습니다.
strip("Just text <img src='https://assets.rbl.ms/4155638/980x.jpg'>")
문자열에 HTML이 포함되어 있지 않은 경우 (예 : 양식 필드에서 HTML을 제거하려는 경우) jQuery 메소드의 확장으로
jQuery(html).text();`
HTML이 없으면 빈 문자열을 반환합니다
사용하다:
jQuery('<p>' + html + '</p>').text();
대신에.
업데이트 :
의견에서 지적했듯이 어떤 상황 에서이 솔루션은 공격자의 영향 html
을 html
받을 수있는 경우 안에 포함 된 자바 스크립트를 실행 하고 다른 솔루션을 사용합니다.
$("<p>").html(html).text();
jQuery('<span>Text :) <img src="a" onerror="alert(1)"></span>').text()
hypoxide에 의해 게시 된 위의 기능은 정상적으로 작동하지만 기본적으로 웹 RichText 편집기 (예 : FCKEditor)에서 생성 된 HTML을 변환하고 모든 HTML을 지우고 HTML과 STMP 전자 메일에 올바른 부분을 만드는 데 도움이되는 일반 텍스트 버전 (HTML 및 일반 텍스트)
오랜 시간 동안 Google을 직접 검색 한 후 동료가 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
일종의 시각적 형식이 유지되도록 (줄 바꿈 문자)로 바꿨습니다.
링크 형식 (예 :)을 변경하려면을 BBC (Link->http://www.bbc.co.uk)
편집하십시오 $2 (Link->$1)
. 여기서 $1
href URL / URI $2
는 하이퍼 링크 텍스트입니다. 일반 텍스트 본문에 직접 링크가 있으면 대부분의 SMTP 메일 클라이언트가이를 변환하여 사용자가 해당 링크를 클릭 할 수 있습니다.
이 정보가 도움이 되길 바랍니다.
허용 된 답변 개선.
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 이상이 안전합니다. 오페라 프레스토는 여전히 취약하다. 또한 문자열에 언급 된 이미지는 Chromium 및 Firefox에서 http 요청을 저장하여 다운로드되지 않습니다.
<script><script>alert();
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, '');
<html><style..>* {font-family:comic-sans;}</style>Some Text</html>
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 "normal text" and stuff using <html encoding>
</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(/ /gi," ");
returnText=returnText.replace(/&/gi,"&");
returnText=returnText.replace(/"/gi,'"');
returnText=returnText.replace(/</gi,'<');
returnText=returnText.replace(/>/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 />
/<p.*>/gi
해야 한다고 생각 합니다 /<p.*?>/gi
.
<br>
태그 를 제거 하려면 대신 좋은 정규 표현식을 사용할 수 있습니다. /<br\s*\/?>/
이 방법으로 3 대신 1을 대체 할 수 있습니다. 엔티티의 디코딩을 제외하고 단일 정규 표현식을 가질 수있는 것처럼 보입니다 /<[a-z].*?\/?>/
.
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, "");
nickf 나 Shog9보다 덜 우아한 다른 솔루션은 <body> 태그에서 시작하여 DOM을 재귀 적으로 살펴보고 각 텍스트 노드를 추가하는 것입니다.
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;
}
링크와 내용의 구조 (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>
require.js 와도 작동합니다.
define(["textversionjs"], function(createTextVersion) {
var yourHtml = "<h1>Your HTML</h1><ul><li>goes</li><li>here.</li></ul>";
var textVersion = createTextVersion(yourHtml);
});
모든 답변을 시도한 후 모든 사례가 최우선 사례가 아니고 내 요구를 완전히 지원할 수는 없었지만 가장 많이 언급했습니다.
php가 어떻게 작동하는지 탐구하기 시작했고 여기에서 strip_tags 메소드를 복제하는 php.js lib를 발견했습니다 : http://phpjs.org/functions/strip_tags/
allowed == ''
OP가 요구 한 것, 즉 Byron이 아래에서 대답 한 것 (Byron 만 [^>]
잘못 알고 있음) 이라고 생각할 때 더 빠르게 만들 수 있습니다 .
allowed
매개 변수 를 사용하면 XSS에 취약합니다. stripTags('<p onclick="alert(1)">mytext</p>', '<p>')
반환<p onclick="alert(1)">mytext</p>
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/
끔찍한 일을하는 최고의 답변 데모 :
string with <a malicious="attribute \">this text should be removed, but is not">example</a>
.
많은 사람들이 이미 이것을 대답했지만 문자열에서 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>
가장 쉬운 방법은 위에서 언급 한 것처럼 정규 표현식을 사용하는 것입니다. 그것들을 많이 사용할 이유가 없지만. 시험:
stringWithHTML = stringWithHTML.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, "");
[^<>]
으로[^>]
유효한 태그가 포함 할 수 없기 때문에 <
문자를, 다음 XSS 취약점이 사라집니다.
원래 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");
@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("");
그러나 다른 이유로도 완벽한 솔루션은 아닙니다.
iframe 샌드 박스 속성을 사용하여 HTML 태그를 안전하게 제거 할 수 있습니다. .
여기서 아이디어는 문자열을 정규 표현식으로 변환하는 대신 텍스트를 DOM 요소에 삽입 한 다음 해당 요소 의 textContent
/ innerText
속성 을 쿼리하여 브라우저의 기본 파서를 활용 한다는 것입니다.
텍스트를 삽입하는 데 가장 적합한 요소는 샌드 박스 iframe으로, 임의의 코드 실행을 방지 할 수 있습니다 ( 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));
let
및 const
연산자 를 사용하여 블록 범위를 올바르게 지정 했으므로 IIFE를 사용하지 않아야합니다 . 또한 귀하의 솔루션을 iframes
사용하여 문서 내부에서 사용되지 않은 것에 대한 많은 참고 자료를 얻었습니다 . document.body.removeChild(sandbox)
미래의 복사 파스타 기반 독자를 위해 코드에 코드를 추가하는 것을 고려하십시오 .
아래 코드를 사용하면 일부 HTML 태그를 유지하면서 다른 모든 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 : '';
});
}
phpjs
)를 인용해야합니다 . 이 allowed
매개 변수 를 사용하면 XSS에 취약합니다. stripTags('<p onclick="alert(1)">mytext</p>', '<p>')
반환<p onclick="alert(1)">mytext</p>
환상적인 htmlparser2 순수 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과 같은 도구를 사용하여 웹 응용 프로그램을 압축하면 노드와 브라우저 모두에서 작동합니다.
방금 스트립을 제거해야했습니다 <a>
태그 하고 링크 텍스트로 교체해야했습니다.
이것은 잘 작동하는 것 같습니다.
htmlContent= htmlContent.replace(/<a.*href="(.*?)">/g, '');
htmlContent= htmlContent.replace(/<\/a>/g, '');
title="..."
.
더 쉬운 해결책을 위해 이것을 시도하십시오 => https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/
var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");
HTML을 제거하는 간단한 2 줄 jquery.
var content = "<p>checking the html source </p><p>
</p><p>with </p><p>all</p><p>the html </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
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;
}
(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);