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

Flask中如何将Python函数输出转为合法JSON并传递给HTML内嵌JS

解决Flask串口数据转JSON并在前端展示的问题

问题根源

  1. /loaddata路由返回Python集合{output2},Flask无法将集合序列化为合法JSON,且响应头未设置为application/json,导致前端response.json()解析失败。
  2. 前端document.write(data)存在作用域错误:data是fetch回调内的局部变量,页面初始化时无法访问;同时document.write会覆盖页面内容,不适合动态更新数据。
  3. 每次请求都重新打开串口,易引发资源占用、连接异常等问题。

解决方案

1. 修复/loaddata路由,返回合法JSON

修改路由代码,返回包含数据的字典(Flask会自动将字典序列化为JSON并设置正确响应头),用with语句管理串口连接避免资源泄漏,添加异常处理:

import serial
import time
from flask import Flask, jsonify

# 假设app已完成初始化
@app.route('/loaddata', methods=['GET'])
def loaddata():
    try:
        # with语句自动管理串口连接,请求结束后自动关闭
        with serial.Serial(
            port='/dev/ttyACM0',
            baudrate=57600,
            timeout=1
        ) as ser:
            ser.reset_input_buffer()
            output2 = ""
            for x in range(8):
                line = ser.readline().decode('utf-8').rstrip()
                print(line)
                output2 += line + "\n"  # 添加换行符,让每行数据在前端更易读
                time.sleep(0.01)
            print("connected to: " + ser.portstr)
            # 返回包含数据的字典,Flask自动转JSON并设置响应头
            return jsonify({"sensor_data": output2})
    except Exception as e:
        # 捕获异常并返回错误信息,方便排查问题
        return jsonify({"error": str(e)}), 500

2. 修复前端代码,正确接收并展示数据

修改sensor路由的HTML部分,添加数据展示容器,并在fetch回调中更新DOM:

@app.route('/sensor', methods=['GET', 'POST'])
def sensor():
    output = '''<!DOCTYPE html>
<html lang="en">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        body{
            background: #005E60;  
            background-size: 100% 100%;
            height: 100vh;
            /* 保留原有样式 */
        }
        #sensor-data {
            color: white;
            font-size: 18px;
            margin-top: 20px;
            white-space: pre-wrap; /* 保留换行符,让数据格式更清晰 */
        }
    </style>   
</head>
<body>
    <div class="Box">
        <div class="flex-box">
            <p><a href='http://172.23.2.132:5000/camera' style='width: 210px; height:80px;color:white; font-size: 23px; '>Click here to get back</a></p>
            <!-- 添加专门的容器用于展示传感器数据 -->
            <div id="sensor-data"></div>
        </div> 
    </div>

    <script type="text/javascript">
        function loop(){
            fetch('/loaddata')
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                return response.json();
            })
            .then(data => {
                console.log('Data received:', data);
                const dataContainer = document.getElementById('sensor-data');
                // 处理正常数据和错误情况
                if (data.error) {
                    dataContainer.textContent = "Error: " + data.error;
                } else {
                    dataContainer.textContent = data.sensor_data;
                }
            })
            .catch(error => {
                console.error('There was a problem with the fetch operation:', error);
                document.getElementById('sensor-data').textContent = "Fetch error: " + error.message;
            });
        }

        var intervalId = window.setInterval(loop, 1000);
    </script>
</body>
</html>'''
    return output

关键说明

  • 使用jsonify返回响应:Flask的jsonify函数会自动处理JSON序列化,并设置Content-Type: application/json响应头,确保前端能正确解析。
  • 串口连接优化:with语句自动关闭串口,避免多次请求导致的串口占用问题。
  • 前端DOM更新:通过指定容器的textContent更新数据,避免document.write的副作用,同时处理错误情况提升体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 09:53:21