如何在NextJS页面中正确展示API返回的HTML格式图表
问题排查与解决方案
核心问题原因
- 错误使用script标签加载HTML资源:你的后端接口返回的是完整的HTML内容,不是JavaScript脚本,用
<script src>加载HTML资源属于资源类型不匹配,浏览器不会把返回的HTML渲染到页面上。 - 浏览器不支持自闭合script标签:HTML规范中
<script>标签不能使用自闭合写法,必须写为<script></script>,即使资源类型匹配,这种写法也会导致解析失败。 - React/Next.js默认不解析动态插入的HTML内容:如果你要直接插入后端返回的HTML字符串,不能靠script标签加载,需要用React提供的
dangerouslySetInnerHTML属性处理。 - 可能存在跨域问题:如果你的NextJS应用不是部署在
127.0.0.1:8000同域名下,直接请求本地8000端口的接口会触发浏览器CORS跨域限制,导致请求失败。 - Plotly生成的HTML包含内联脚本:Plotly的
to_html方法生成的HTML中自带执行所需的JS代码,直接插入到页面中时,React默认不会执行插入的HTML里的脚本,需要额外处理。
正确实现方案
方案1:用iframe直接加载接口(最简单稳定)
iframe会自动解析完整的HTML内容,还能避免不同页面的脚本冲突,不需要额外处理脚本执行问题:
<div className="grid"> <p className="description"> In this graph you can see the activity performed. </p> {isLoading && <p className="loading">Loading graph...</p>} <div className="graph"> <iframe src={`http://127.0.0.1:8000/showGraph/graph/${id}`} width="100%" height="600px" frameBorder="0" /> </div> </div>
方案2:请求HTML后插入页面
如果不想用iframe,可以先请求HTML字符串再插入页面:
import { useEffect, useState } from 'react' export default function GraphPage({ id }) { const [graphHtml, setGraphHtml] = useState('') const [isLoading, setIsLoading] = useState(true) useEffect(() => { const fetchGraph = async () => { try { const res = await fetch(`http://127.0.0.1:8000/showGraph/graph/${id}`) const html = await res.text() setGraphHtml(html) } catch (err) { console.error('图表加载失败', err) } finally { setIsLoading(false) } } fetchGraph() }, [id]) return ( <div className="grid"> <p className="description"> In this graph you can see the activity performed. </p> {isLoading && <p className="loading">Loading graph...</p>} <div className="graph" dangerouslySetInnerHTML={{ __html: graphHtml }} /> </div> ) }
后端跨域配置补充
如果存在跨域报错,在FastAPI后端添加CORS中间件:
from fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins=["*"], # 生产环境替换为你的NextJS实际部署域名 allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
内容的提问来源于stack exchange,提问作者a.v. Magia
相关产品推荐
相关产品推荐

