从wordpress api渲染pre-escaped html with react

时间:2017-08-07 06:49:56

标签: javascript reactjs rendering wordpress-rest-api

我使用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?

1 个答案:

答案 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}} />
  )
}