我有一些用户从文本区域生成的 html 标记,我想在屏幕的另一部分呈现它。标记以字符串形式保存在组件的 props 中。
出于显而易见的原因,我不想使用危险的sethtml。是否有诸如标记的解析器,但用于 html,以便它去除脚本标记和其他无效的 html。
我有一些用户从文本区域生成的 html 标记,我想在屏幕的另一部分呈现它。标记以字符串形式保存在组件的 props 中。
出于显而易见的原因,我不想使用危险的sethtml。是否有诸如标记的解析器,但用于 html,以便它去除脚本标记和其他无效的 html。
消毒使用的HTML的sanitize-HTMLmodule,并呈现使用消毒串dangerouslySetInnerHTML。
您可以创建一个简单的包装组件:
const defaultOptions = {
allowedTags: [ 'b', 'i', 'em', 'strong', 'a' ],
allowedAttributes: {
'a': [ 'href' ]
},
allowedIframeHostnames: ['www.youtube.com']
};
const sanitize = (dirty, options) => ({
__html: sanitizeHtml(
dirty,
options: { ...defaultOptions, ...options }
)
});
const SanitizeHTML = ({ html, options }) => (
<div dangerouslySetInnerHTML={sanitize(html, options)} />
);
用法:
<SanitizeHTML html="<img src=x onerror=alert('img') />" />
您还可以使用react-sanitized-html的 SanitizedHTML 组件,它是一个围绕sanitize-html
以下内容的react包装器:
<SanitizedHTML
allowedAttributes={{ 'a': ['href'] }}
allowedTags={['a']}
html={ `<a href="http://bing.com/">Bing</a>` }
/>
基于已接受答案的示例:
import sanitizeHtml from 'sanitize-html';
const MyComponent = () => {
dirty = '<a href="my-slug" target="_blank" onClick="evil()">click</a>';
const clean = sanitizeHtml(dirty, {
allowedTags: ['b', 'i', 'em', 'strong', 'a'],
allowedAttributes: {
a: ['href', 'target']
}
});
return (
<div
dangerouslySetInnerHTML={{__html: clean}}
/>
);
};
MyComponent
渲染div
包含不带链接的链接onClick="evil()"
:
<a href="my-slug" target="_blank">click</a>
对于 XSS 过滤,有一个很好的替代安全人员编写的sanitize-html,称为dompurify。
以下是https://stackoverflow.com/a/38663813/1762849 中的包装器与 DOMPurify 的外观:
const defaultOptions = {
ALLOWED_TAGS: [ 'b', 'i', 'em', 'strong', 'a' ],
ALLOWED_ATTR: ['href']
};
const sanitize = (dirty, options) => ({
__html: DOMPurify.sanitize(
dirty,
{ ...defaultOptions, ...options }
)
});
const SanitizeHTML = ({ html, options }) => (
<div dangerouslySetInnerHTML={sanitize(html, options)} />
);
用法:
<SanitizeHTML html="<img src=x onerror=alert('img') />" />
此外,如果您需要清理客户端和服务器上的 HTML,请考虑使用isomophic-dompurifymodule,该module在前端和后端统一使用 DOMPurify。