在HTML页面中通过JavaScript运行Python代码,核心思路是借助能够在浏览器环境运行的Python运行时,或者通过前后端交互将Python执行逻辑放到后端处理。目前最主流的浏览器端直接运行方案是使用Pyodide,它是Python的科学计算包到WebAssembly的移植版本,可以让Python在浏览器中直接执行。

方案一:使用Pyodide在浏览器端直接运行Python
Pyodide会将Python解释器和常用科学计算库编译为WebAssembly,加载到页面后就可以直接通过JavaScript调用Python代码执行,不需要后端参与。
1. 引入Pyodide运行时
首先在HTML中引入Pyodide的CDN资源,等待运行时加载完成后再执行后续操作。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML用js运行python示例</title>
</head>
<body>
<button id="runBtn">运行Python代码</button>
<div id="result"></div>
<!-- 引入Pyodide CDN -->
<script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script>
<script>
// 后续js逻辑写在这里
</script>
</body>
</html>
2. 编写JavaScript调用Python的逻辑
加载Pyodide需要一定时间,我们需要先等待运行时初始化完成,再通过pyodide.runPython方法执行Python代码。
// 等待Pyodide加载完成
let pyodide;
async function initPyodide() {
pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/"
});
console.log("Pyodide加载完成");
}
initPyodide();
// 点击按钮执行Python代码
document.getElementById("runBtn").addEventListener("click", async () => {
if (!pyodide) {
document.getElementById("result").innerText = "Pyodide还在加载中,请稍候";
return;
}
// 要执行的Python代码,计算1到100的和
const pythonCode = `
def calc_sum():
total = 0
for i in range(1, 101):
total += i
return total
result = calc_sum()
`;
try {
// 执行Python代码
pyodide.runPython(pythonCode);
// 获取Python中定义的result变量的值
const sumResult = pyodide.globals.get("result");
document.getElementById("result").innerText = `1到100的和是:${sumResult}`;
} catch (e) {
document.getElementById("result").innerText = `执行出错:${e.message}`;
}
});
3. Python和JavaScript变量交互
Pyodide支持Python和JavaScript之间的变量传递,除了获取全局变量,还可以将JavaScript的变量传入Python中使用。
// 传入JavaScript变量到Python环境
const jsNum = 20;
pyodide.globals.set("js_input_num", jsNum);
const pythonCode = `
py_result = js_input_num * 3 + 10
`;
pyodide.runPython(pythonCode);
const pyResult = pyodide.globals.get("py_result");
console.log(`Python计算结果:${pyResult}`); // 输出70
方案二:通过后端接口转发执行Python
如果Python代码依赖复杂的第三方库,或者需要操作服务器本地资源,浏览器端的Pyodide可能无法满足需求,此时可以通过JavaScript调用后端接口,由后端执行Python代码后返回结果。
1. 后端Python接口示例(Flask框架)
后端使用Flask编写一个简单的接口,接收前端传入的Python代码并执行,返回执行结果。
from flask import Flask, request, jsonify
import sys
import io
app = Flask(__name__)
@app.route("/run-python", methods=["POST"])
def run_python():
code = request.json.get("code", "")
if not code:
return jsonify({"error": "未传入Python代码"}), 400
# 捕获Python执行的标准输出
old_stdout = sys.stdout
sys.stdout = buffer = io.StringIO()
try:
exec(code)
output = buffer.getvalue()
return jsonify({"result": output})
except Exception as e:
return jsonify({"error": str(e)}), 500
finally:
sys.stdout = old_stdout
if __name__ == "__main__":
app.run(host="127.0.0.1", port=5000, debug=True)
2. 前端JavaScript调用接口
前端通过fetch方法将Python代码发送到后端接口,获取执行结果后展示在页面上。
document.getElementById("runBtn").addEventListener("click", async () => {
const pythonCode = `
import math
print(f"圆周率的值是:{math.pi}")
print(f"100的平方根:{math.sqrt(100)}")
`;
try {
const response = await fetch("http://127.0.0.1:5000/run-python", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ code: pythonCode })
});
const data = await response.json();
if (data.error) {
document.getElementById("result").innerText = `执行出错:${data.error}`;
} else {
document.getElementById("result").innerText = data.result;
}
} catch (e) {
document.getElementById("result").innerText = `请求出错:${e.message}`;
}
});
两种方案对比
我们可以根据实际需求选择合适的方案,两种方案的特点对比如下:
| 对比维度 | Pyodide浏览器端方案 | 后端接口转发方案 |
|---|---|---|
| 是否需要后端 | 不需要 | 需要 |
| 执行环境 | 用户浏览器 | 服务器 |
| 第三方库支持 | 仅支持已移植到WebAssembly的库 | 支持所有Python第三方库 |
| 资源占用 | 占用用户浏览器资源,加载包体积较大 | 占用服务器资源 |
| 适用场景 | 简单计算、前端轻量Python逻辑 | 复杂逻辑、依赖特殊库、操作服务器资源 |
注意事项
- 使用Pyodide时,首次加载需要下载约10MB左右的运行时文件,建议添加加载状态提示,提升用户体验。
- 后端执行Python代码时,不要直接执行用户传入的任意代码,避免命令注入风险,生产环境需要添加代码沙箱限制。
- Pyodide目前对部分Python标准库的支持还不完善,使用前可以查看官方文档确认所需功能是否支持。
- 如果后端接口部署在公网,注意配置跨域规则,允许前端页面的域名访问接口。
HTMLJavaScriptPythonPyodide修改时间:2026-07-19 12:21:36