反应:使用危险的SetInnerHTML插入时脚本标签不起作用

2022-01-31 00:00:00 reactjs javascript html script-tag

我正在尝试使用 React 中的 dangerouslySetInnerHTML 属性将从我的服务器发送的 html 设置为在 div 中显示.我在其中也有脚本标记,并使用在该 html 中定义的函数.我在 JSFiddle here 中做了错误示例.

I'm trying to set html sent from my server to show inside a div using dangerouslySetInnerHTML property in React. I also have script tag inside it and use functions defined in same inside that html. I have made example of error in JSFiddle here.

这是测试代码:

var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';

var Hello = React.createClass({
  displayName: 'Hello',
  render: function() {
    return (<div dangerouslySetInnerHTML={{__html: x}} />);
  }
});

我检查了脚本标签已添加到 DOM,但无法调用该脚本标签中定义的函数.如果这不是正确的方法,是否还有其他方法可以注入脚本标签的内容.

I checked and the script tag is added to DOM, but cannot call the functions defined within that script tag. If this is not the correct way is there any other way by which I can inject the script tag's content.

推荐答案

这里有一个有点脏的方法,关于这里发生的事情的一些解释,您通过正则表达式提取脚本内容,并仅使用 react 渲染 html,然后在安装组件后,脚本标记中的内容在全局范围内运行.

Here's a bit of a dirty way of getting it done , A bit of an explanation as to whats happening here , you extract the script contents via a regex , and only render html using react , then after the component is mounted the content in script tag is run on a global scope.

var x = '<html><scr'+'ipt>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</scr'+'ipt><body><p onClick="pClicked()">Hello</p></body></html>';

var extractscript=/<script>(.+)</script>/gi.exec(x);
x=x.replace(extractscript[0],"");

var Hello = React.createClass({
  displayName: 'Hello',
  componentDidMount: function() {
    // this runs the contents in script tag on a window/global scope
    window.eval(extractscript[1]);

  },
  render: function() {
    return (<div dangerouslySetInnerHTML={{__html: x}} />);
  }
});

ReactDOM.render(
  React.createElement(Hello),
  document.getElementById('container')
);

相关文章