问题
How to get script inside dangerouslySetInnerHTML get executed?
class Page extends Component {
render() {
return (
<script
dangerouslySetInnerHTML={{ __html: `
console.log('hello world');
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'viewCart'
});
` }}
/>
);
}
}
I can't get console.log('hello world')
executed. Anybody can help? Thank you
回答1:
You can't because script tags are removed automatically for security.
The best way to work with javascript is to get the string separately and execute (or eval) it from componentWillMount or componentDidMount
class Page extends Component {
componentDidMount() {
const jsCode = `
console.log('hello world');
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'viewCart'
})
`;
new Function(jsCode)();
}
// you can do something else here
render() {
return (
<noscript />
);
}
}
You can obviously use any string. I presume you might be loading it from the server.
In the example above I used new Function()()
which is very similar to eval()
but works faster.
I used componentDidMount
so i'm certain the script executes after the view is shown. Another difference between Will and Did mount is that Will mount executes on both server and client sides of universal (isomorphic) apps, whereas Did mount will only execute on the client side of universal apps.
回答2:
Script elements don't get executed because of the way that react-dom
creates them.
When ReactDOM.createElement
receives a type of 'script'
it uses .innerHTML
instead of using document.createElement
like you might expect.
var div = document.createElement('div');
div.innerHTML = '<script></script>';
var element = div.removeChild(div.firstChild);
Creating the script in this way sets the "parser-inserted" flag on that element to true. This flag tells the browser that it should not execute.
https://github.com/facebook/react/blob/c2a2d8a539bf02e40c43d36adc2826e228f30955/packages/react-dom/src/client/ReactDOMComponent.js#L406
https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#Security_considerations
https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml0
来源:https://stackoverflow.com/questions/37803559/react-js-how-to-get-script-inside-dangerouslysetinnerhtml-executed