我使用wordpress api输出存储的数据,并做出反应以在视图中呈现数据。
看起来像wordpress api将帖子输出为预先转义的HTML字符串,如下所示:
content {
rendered: "<p>This is a post</p><p>This is some more text</p>"
}
看起来反应正在呈现包含标签作为字符串的完整html。我猜这可以做到:
render() {
const post = content.rendered ? content.rendered : "";
return <div dangerouslySetInnerHTML={{__html: post}}></div>;
}
但是通过这个名字,我可以看到这可能不是最好的解决方案,而且每次我从其余的api渲染数据时我都不想这样做。有没有办法让这些html字符串被视为除此之外的html?
答案 0 :(得分:1)
据https://reactjs.org/docs/dom-elements.html我所知,该属性的命名是为了让自己远离自己。从理论上讲,有人可能会在您尝试呈现的HTML输出中添加恶意内容。您可以使用其他属性。
我能想到的唯一安全的解决方案是手动删除标签 - 无论是所有标签还是只是潜在的恶意标签。我写了一篇POC(下面,非常感谢Removing all script tags from html with JS Regular Expression的回答)。
这仍然使用dangerouslySetInnerHTML
属性,但它不那么危险,因为我正在删除所有<script>
和<style>
标记。您可以编辑它以删除您需要的任何其他内容(或使用*
选择器删除所有内容)。
// Function that takes the original content and strips out all <script> and <style> tags.
cleanHtml(content) {
let div = document.createElement('div');
div.innerHTML = content;
let scripts = div.querySelectorAll('style, scripts');
let i = scripts.length;
while (i--) {
scripts[i].parentNode.removeChild(scripts[i]);
}
return div.innerHTML;
}
render() {
let content = this.cleanHtml(content.rendered);
return (
<div dangerouslySetInnerHTML={{ __html: content}} />
)
}