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

每秒刷新SVG运行数分钟后无法显示问题求助

问题描述
  • 我是HTML、SVG、JavaScript等Web编程相关技术的新手,需要制作一个数据总览网页,展示设备采集到的各类信息。
  • 我已经编写了Python脚本读取物理设备数据,脚本可以修改SVG文件中不同图形组件的fill填充色属性,希望能把采集到的数据实时更新展示在网页上。
  • 我使用的示例SVG文件内容如下:
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
<g id="Layer_1">
  <title>Layer 1</title>
  <rect id="svg_1" height="386" width="527" y="94" x="150" stroke="#231F20" fill="yellow"/>
  <rect id="svg_2" height="386" width="527" y="114" x="450" stroke="#231F20" fill="yellow"/>
 </g>
</svg>
  • Python脚本会修改id="svg_1"、id="svg_2"这类元素的fill属性,目前我用如下HTML文件展示SVG:
<!DOCTYPE html>
<html>
<head>
  <title>HTML SVG</title>
</head>
<body>
  <h1>Design</h1>
          <img id="demo" alt="" height="600" onload="javascript:(function()

{setTimeout(function(
{document.getElementById('demo').src=document.getElementById('demo').src.split('?'
[0]+'?time='+new Date().getTime();},1000);}())" src="ee.svg" width="800" />
</body>
</html>
  • 上述JavaScript实现了每秒刷新一次SVG文件的逻辑,这个简易方案刚开始可以正常运行数分钟,但之后SVG就无法正常显示,需要可行的技术解决方案。
故障原因

现有方案跑久了失效,核心是两个问题:

  1. 刷新逻辑有缺陷:固定1秒无脑触发刷新,完全不判断上一次SVG是否加载完成。如果碰到Python正在写入SVG的瞬间发起请求,要么拿到写了一半的损坏文件,要么请求超时堆积,请求堆多了浏览器会直接拦截后续请求,自然无法正常显示。
  2. 每次全量重载SVG会持续占用浏览器缓存和内存,运行时间长了资源占满就会加载失败。
解决方案

给你两个从易到难的方案,新手可以直接选第一个落地。

方案1:修复现有逻辑(改动最小)

首先把写在标签属性里的零散JS抽离,加加载锁、预加载校验、错误重试逻辑,避免请求堆积和损坏内容渲染:

<!DOCTYPE html>
<html>
<head>
  <title>HTML SVG</title>
</head>
<body>
  <h1>Design</h1>
  <img id="demo" alt="" height="600" src="ee.svg" width="800" />
  <script>
    const svgDom = document.getElementById('demo')
    let isLoading = false
    function refreshSvg() {
      // 上一次加载还没完成的话,直接跳过本轮刷新
      if (isLoading) return
      isLoading = true
      // 用临时图片预加载,加载成功再替换正式src,避免显示损坏内容
      const tempImg = new Image()
      tempImg.onload = () => {
        svgDom.src = tempImg.src
        isLoading = false
        // 加载成功后等1秒再触发下一轮刷新
        setTimeout(refreshSvg, 1000)
      }
      tempImg.onerror = () => {
        isLoading = false
        // 加载失败的话等200毫秒重试,不要持续发请求打满队列
        setTimeout(refreshSvg, 200)
      }
      tempImg.src = 'ee.svg?time=' + new Date().getTime()
    }
    // 页面首次加载完成后启动刷新循环
    svgDom.onload = () => {
      setTimeout(refreshSvg, 1000)
    }
  </script>
</body>
</html>

同时要修改Python写SVG文件的逻辑:不要直接覆盖ee.svg,先把更新后的SVG内容写到临时文件(比如ee.svg.tmp),确认内容全部写入完成后,再把临时文件重命名为ee.svg。文件重命名是原子操作,可以保证网页请求SVG的时候永远拿到完整文件,不会读到半写入的损坏内容。

方案2:内联SVG+局部更新(长期运行最稳定)

不要用<img>标签加载外部SVG,直接把SVG代码内联写到HTML里,后续不用重载整个SVG文件:

  • 把SVG内容直接写到HTML页面中,删掉原来的img标签
  • Python端不用每次重写整个SVG文件,只需要输出一个简单的文本/JSON接口,返回类似{"svg_1": "red", "svg_2": "green"}的结构,key是SVG元素ID,value是要设置的填充色
  • 前端JS每秒请求一次这个轻量接口,拿到数据后直接修改对应SVG元素的fill属性即可,请求体积极小,也不会出现文件损坏、资源占用过高的问题,可以长期稳定运行。

内容的提问来源于stack exchange,提问作者Marcin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 01:45:52