如何在Next.js项目中添加带内联脚本的iframe?
在Next.js项目中实现Datawrapper iframe的React风格方案
我需要将以下带内联脚本的iframe添加到Next.js项目中:
<iframe class="plot" aria-label="Map" id="datawrapper-chart-${id}" src="https://datawrapper.dwcdn.net/${id}/1/" style="width: 0; min-width: 100% !important; overflow: scroll; flex-grow: 1" data-external="1" ></iframe> <script type="text/javascript"> !(function () { "use strict"; window.addEventListener("message", function (a) { if (void 0 !== a.data["datawrapper-height"]) { var e = document.querySelectorAll("iframe"); for (var t in a.data["datawrapper-height"]) for (var r = 0; r < e.length; r++) if (e[r].contentWindow === a.source) { var i = a.data["datawrapper-height"][t] + "px"; e[r].style.height = i; } } }); })(); </script>
我已经用dangerouslySetInnerHTML实现了功能,但想找到更符合React风格的实现方式。试过直接照搬代码、去掉函数调用等方法,都没有效果。
解决方案:封装React组件
通过React Hooks处理消息监听,替代内联脚本,实现更安全、更符合React范式的写法:
1. 创建可复用组件
import { useEffect, useRef } from 'react'; const DatawrapperChart = ({ id }) => { const iframeRef = useRef(null); useEffect(() => { // 处理Datawrapper发来的高度调整消息 const handleMessage = (event) => { if (event.data['datawrapper-height'] && event.data['datawrapper-height'][id]) { const targetHeight = event.data['datawrapper-height'][id]; if (iframeRef.current) { iframeRef.current.style.height = `${targetHeight}px`; } } }; // 添加消息监听 window.addEventListener('message', handleMessage); // 组件卸载时移除监听,避免内存泄漏 return () => { window.removeEventListener('message', handleMessage); }; }, [id]); return ( <iframe ref={iframeRef} className="plot" aria-label="Map" id={`datawrapper-chart-${id}`} src={`https://datawrapper.dwcdn.net/${id}/1/`} style={{ width: 0, minWidth: '100%', overflow: 'scroll', flexGrow: 1 }} data-external="1" /> ); }; export default DatawrapperChart;
2. 在项目中使用组件
在需要展示图表的页面或组件中导入并使用:
import DatawrapperChart from '../components/DatawrapperChart'; const ChartPage = () => { return ( <div style={{ display: 'flex', flexDirection: 'column' }}> <DatawrapperChart id="你的图表ID" /> </div> ); }; export default ChartPage;
方案优势
- 规避
dangerouslySetInnerHTML带来的XSS安全风险 - 精准针对当前iframe处理消息,无需遍历所有iframe,性能更优
- 组件化设计,可在项目中多处复用,维护更方便
内容的提问来源于stack exchange,提问作者BurgerBurglar
相关产品推荐
相关产品推荐

