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

Python Flask发送JPEG图像原始HTTP响应浏览器显示为文本问题

第一种写法失效的核心原因
  1. 框架层逻辑错误:Flask的Response对象本身已经封装了HTTP响应的协议组装逻辑,不需要手动写HTTP/1.1 200 OK状态行,也不需要自己拼响应头和响应体的分隔空行。把这些协议字段全部传给set_data()时,这些内容会被完整当成响应体处理,Flask会自动生成默认的响应头(Content-Type: text/html; charset=utf-8),浏览器收到的响应头里根本没有手写的image/jpeg声明,自然会把所有内容当纯文本渲染。
  2. 二进制数据处理错误:用str(frm)把JPEG格式的二进制字节流转成字符串是完全错误的。Python中对bytes类型调用str()会生成带b''前缀、包含转义字符的字符串表示,不是原始的图片二进制内容,即便响应头设置正确,这部分内容也无法被解码为正常图片。
  3. 换行符不符合规范:HTTP协议(RFC 7230)明确要求所有行的结束符必须是\r\n(CRLF),单独使用\n不符合协议标准,部分严格的浏览器/代理会直接解析失败,但这个问题在错误写法中优先级最低——因为手动拼接的头根本没走到HTTP协议解析的步骤。
正确实现方式

第二种初始化Response的方式就是符合框架设计的标准写法,不需要做多余的协议拼接:

  • 直接把JPEG原始字节流作为响应体传入
  • 通过headers参数设置Content-Type为image/jpeg
  • 状态码、Content-Length、响应头和响应体的分隔、行结束符全部由Flask自动处理,不需要手动干预。

单帧图片返回的完整可运行示例:

from flask import Flask, Response
import cv2

app = Flask(__name__)
# 初始化默认摄像头
cap = cv2.VideoCapture(0)

@app.route("/")
def get_single_frame():
    ret, frame = cap.read()
    if not ret:
        return "摄像头帧读取失败", 500
    # 编码为JPEG字节流
    jpeg_bytes = cv2.imencode('.jpg', frame)[1].tobytes()
    # 直接返回二进制数据,指定对应媒体类型
    return Response(jpeg_bytes, headers={"Content-Type": "image/jpeg"})

if __name__ == "__main__":
    app.run(debug=True)

如果需要实现实时摄像头流推送,需要用MJPEG多段替换格式,这时候只有响应体内部的分帧边界需要手动拼接\r\n,外层HTTP响应依然交给框架处理:

def generate_stream():
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        jpeg_bytes = cv2.imencode('.jpg', frame)[1].tobytes()
        # 仅响应体内部分帧格式需要手动写分隔符和行结束符
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n'
               + jpeg_bytes + b'\r\n')

@app.route("/stream")
def video_stream():
    return Response(generate_stream(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

注意:只有在自定义响应体内部的子协议格式(比如MJPEG流分帧)时,才需要手动处理\r\n换行,HTTP响应外层的状态行、公共响应头全部交给Web框架处理即可,不要手动拼接这部分内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 01:42:22