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

Flask集成OpenCV扫码器重定向功能失效问题求助

问题原因

你在gen()生成器里返回redirect('/output/')完全无效——这个生成器是用来输出视频流帧数据的,对应的HTTP响应是multipart/x-mixed-replace类型,前端用<img>标签加载该流,根本不会处理重定向指令。而且生成器里的return只会终止生成器,不会触发页面跳转。另外全局变量output在多请求场景下会出现数据冲突,不适合用来存储扫码结果。

解决方案

要实现扫码成功后跳转,得让前端感知到扫码完成,再由前端主动发起跳转。这里用前端轮询检查的方式最容易实现,具体步骤如下:

1. 修改后端代码

from flask import Flask, render_template, Response, redirect, url_for, session, jsonify
import io
import cv2
import sys
from pyzbar import pyzbar

app = Flask(__name__)
# 必须设置secret_key才能使用session
app.secret_key = 'your_random_secret_key'  # 替换成自定义的随机字符串

@app.route('/output/')
def output():
    # 从session获取扫码结果,无结果则返回扫码页面
    barcode_data = session.get('barcode_data')
    if not barcode_data:
        return redirect(url_for('index'))
    return f"扫码结果:{barcode_data}"

@app.route('/scanner')
def index():
    # 进入扫码页时清空旧的扫码结果
    session.pop('barcode_data', None)
    return render_template('scanner.html')

def gen():
    vc = cv2.VideoCapture(0)
    while True:
        read_return_code, frame = vc.read()
        if not read_return_code:
            break
        og = frame.copy()  # 保留原帧用于解码,避免被绘图操作修改
        cv2.rectangle(frame,(200,170),(450,330),(0,255,100),7)
        frame = cv2.flip(frame, 1)
        decode = pyzbar.decode(og)
        if decode:
            # 提取第一个条码的内容并转成字符串
            barcode_data = decode[0].data.decode('utf-8')
            session['barcode_data'] = barcode_data
            vc.release()
            break  # 终止生成器,停止视频流输出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            vc.release()
            break
      
        encode_return_code, image_buffer = cv2.imencode('.jpg', frame)
        io_buf = io.BytesIO(image_buffer)
        yield (b'--frame\r\n'
                b'Content-Type: image/jpeg\r\n\r\n' + io_buf.read() + b'\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(
        gen(),
        mimetype='multipart/x-mixed-replace; boundary=frame'
    )

# 新增接口,供前端查询扫码状态
@app.route('/check_scan')
def check_scan():
    return jsonify({
        'success': 'barcode_data' in session,
        'data': session.get('barcode_data')
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True, threaded=False)

2. 修改前端HTML(scanner.html)

添加JavaScript定时查询后端,检测到扫码成功后自动跳转:

<html>
<head>
<style>
body{
font-family: Verdana, sans-serif;
} 
</style>
<title>Scanner</title>
</head>
<body>
<h1>Scanner</h1>
<img src="{{ url_for('video_feed') }}">
<script>
// 每500毫秒查询一次扫码状态
const checkInterval = setInterval(() => {
    fetch('/check_scan')
        .then(res => res.json())
        .then(data => {
            if (data.success) {
                clearInterval(checkInterval); // 停止轮询
                window.location.href = '/output/'; // 跳转到结果页
            }
        })
        .catch(err => console.error(err));
}, 500);
</script>
</body>
</html>

关键改动说明

  • 用session替代全局变量存储扫码结果,避免多用户场景下的数据冲突
  • 生成器gen()在扫码成功后仅终止视频流,不再尝试返回无效的重定向
  • 新增/check_scan接口,供前端主动查询扫码状态
  • 前端通过JavaScript轮询检测状态,主动触发页面跳转

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:10:40