You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:22:42