met*_*ors 19 html javascript script-tag reactjs
我正在尝试使用React中的dangerouslySetInnerHTML属性设置从我的服务器发送的html以显示div内部.我里面也有脚本标签,并使用html中定义的函数.我在这里用JSFiddle做了错误的例子.
这是测试代码:
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}} />);
}
});
Run Code Online (Sandbox Code Playgroud)
我检查并将脚本标记添加到DOM,但无法调用该脚本标记中定义的函数.如果这不是正确的方法,我可以通过其他任何方式注入脚本标记的内容.
小智 26
我创建了一个 React 组件,它的工作原理非常相似,dangerouslySetInnerHtml但另外它会执行它在 html 字符串上找到的所有 js 代码,检查一下,它可能对你有帮助:
https://www.npmjs.com/package/dangerously-set-html-content
Das*_*ith 16
这里有一个简单的方法来完成它,有点解释这里发生了什么,你通过正则表达式提取脚本内容,只使用react渲染html,然后在组件安装后脚本标签中的内容在全局范围内运行.
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')
);
Run Code Online (Sandbox Code Playgroud)
我认为您不需要在+此处使用串联()。
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>';
Run Code Online (Sandbox Code Playgroud)
我认为您可以做到:
var x = '<html><script>alert("this.is.sparta");function pClicked() {console.log("p is clicked");}</script><body><p onClick="pClicked()">Hello</p></body></html>';
Run Code Online (Sandbox Code Playgroud)
由于它已经传递给dangerouslySetInnerHTML了。
但是,让我们回到问题。您不需要使用正则表达式来访问脚本标签的内容。id例如<script id="myId">...</script>,如果添加属性,则可以轻松访问元素。
让我们看一个这样的实现的例子。
const x = `
<html>
<script id="myScript">
alert("this.is.sparta");
function pClicked() {console.log("p is clicked");}
</script>
<body>
<p onClick="pClicked()">Hello</p>
</body>
</html>
`;
const Hello = React.createClass({
displayName: 'Hello',
componentDidMount() {
const script = document.getElementById('myScript').innerHTML;
window.eval(script);
}
render() {
return <div dangerouslySetInnerHTML={{__html: x}} />;
}
});
Run Code Online (Sandbox Code Playgroud)
如果您有多个脚本,则可以添加一个数据属性[data-my-script],例如,然后使用jQuery访问它:
const x = `
<html>
<script data-my-script="">
alert("this.is.sparta");
function pClicked() {console.log("p is clicked");}
</script>
<script data-my-script="">
alert("another script");
</script>
<body>
<p onClick="pClicked()">Hello</p>
</body>
</html>
`;
const Hello = React.createClass({
constructor(props) {
super(props);
this.helloElement = null;
}
displayName: 'Hello',
componentDidMount() {
$(this.helloElement).find('[data-my-script]').each(function forEachScript() {
const script = $(this).text();
window.eval(script);
});
}
render() {
return (
<div
ref={helloElement => (this.helloElement = helloElement)}
dangerouslySetInnerHTML={{__html: x}}
/>
);
}
});
Run Code Online (Sandbox Code Playgroud)
无论如何,最好避免使用eval,因此另一种选择是获取文本并使用原始脚本内容附加新的script标签,而不是调用eval。这个答案暗示了这种方法
| 归档时间: |
|
| 查看次数: |
22686 次 |
| 最近记录: |