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

Pyodide(PyScript)结合JS加载URL图片无法在HTML页面显示问题

问题成因

图片无法正常显示是4个问题叠加导致的:

  • 执行时序不匹配:页面内的原生JS脚本会在浏览器解析到对应位置时立刻执行,但PyScript是异步加载、异步运行Python代码的,JS执行时Python逻辑还没跑完,img_str变量还未生成,赋值操作拿到的是空值。
  • 变量作用域不匹配:<py-script>块内定义的变量默认是块级局部变量,不会自动挂载到pyodide.globals全局对象上,JS侧根本无法访问到这个变量。
  • HTML结构不规范:用于展示图片的文本块、img容器、赋值脚本都写在了</body>闭合标签外侧,属于无效HTML结构,浏览器解析时会出现不可预期的行为。
  • 输出逻辑冲突:你给<py-script>标签设置了output="image"属性,PyScript会默认把块内生成的matplotlib图表自动渲染到对应容器中,和你手动转base64赋值的逻辑互相干扰,导致渲染异常。
修复方案
  • 移除<py-script>标签上多余的output="image"属性,关闭默认自动输出逻辑,避免和手动渲染流程冲突。
  • 直接在Python代码中引入浏览器DOM API完成图片赋值,不需要额外编写原生JS块,从根源上避免跨语言传值的作用域问题、时序问题。
  • 修正HTML结构,把所有页面元素、脚本都移动到<body>标签内部,符合HTML语法规范。
  • 可选优化:绘制图片时关闭matplotlib的坐标轴,调整保存图片的边距,去掉多余的空白区域,展示效果更好。
修复后可直接运行的完整代码
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
        <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
        <py-env>
            - matplotlib
            - imageio
        </py-env>
    </head>
    <body>
        <h1>PyScript - 从API加载图片展示</h1>
        <div>
            <p>
                本页面从cataas获取猫咪图片并展示在下方。
            </p>
        </div>

        <div id="textfield">matplotlib生成的图片:</div>
        <div id="pyplotdiv"><img id="pyplotfigure"/></div>

        <py-script>
from pyodide.http import pyfetch
from io import BytesIO
import matplotlib.pyplot as plt
import imageio.v3 as iio
import io, base64
# 直接引入浏览器document对象,在Python侧操作DOM
from js import document

# 拉取远程图片
response = await pyfetch(url="https://cataas.com/cat", method="GET")
img = iio.imread(BytesIO(await response.bytes()), index=None)

# 绘制图片,关闭坐标轴消除多余UI
plt.imshow(img)
plt.axis('off')

# 将图表转换为base64编码的PNG格式
buf = io.BytesIO()
plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0)
buf.seek(0)
img_str = 'data:image/png;base64,' + base64.b64encode(buf.read()).decode('UTF-8')

# 直接给img标签的src属性赋值
document.getElementById("pyplotfigure").src = img_str
        </py-script>
    </body>
</html>

如果你一定要保留JS侧赋值的实现方式,需要做两处修改:一是在Python代码中显式把变量挂载到JS全局作用域,添加from js import window; window.img_str = img_str;二是把JS赋值逻辑改为监听PyScript执行完成事件后再运行,避免提前执行。这种实现链路更长,容易出问题,不推荐使用。

内容的提问来源于stack exchange,提问作者Vikas Kumar Ojha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:42:37