flask路由中应直接返回二维码图片流:用qrcode.qrcode实例生成(支持中文、自定义box_size和border),bytesio捕获png数据,send_file返回并设cache-control禁用缓存。

Flask路由里直接返回二维码图片流,别写文件
直接用 qrcode.make() 生成二维码,再用 io.BytesIO 转成内存字节流,最后用 send_file() 返回 image/png 响应——全程不落地文件,避免并发写冲突和磁盘清理问题。
-
qrcode.make()默认输出 PIL Image 对象,调用.save()时传BytesIO实例即可捕获 PNG 数据 - 务必指定
mimetype="image/png",否则浏览器可能当文本解析或触发下载 - 别用
Response(..., mimetype="image/png")手动构造——send_file()自动处理缓存头、分块传输等细节
中文内容生成失败?先检查字体和编码
如果二维码内容含中文但扫码后乱码或报错 UnicodeEncodeError,本质是 qrcode 底层用的 base64 编码 + UTF-8 字节流,但某些旧版库默认用 latin-1。最稳解法:显式转字节再 encode。
- 传入内容统一用
text.encode("utf-8").decode("latin-1")绕过编码冲突(这是 qrcode 库兼容性 hack) - 更推荐改用
qrcode.QRCode实例,设置error_correction=qrcode.constants.ERROR_CORRECT_H并手动 add_data,它对 Unicode 更友好 - 别依赖系统默认字体——
qrcode不渲染文字,只编码数据;乱码只发生在你把中文当普通字符串传、而环境 locale 不匹配时
控制尺寸和边距:用 QRCode 类而非快捷函数
qrcode.make() 看似简单,但没法调 border(白边宽度)和 box_size(单个模块像素),必须升级到实例化方式。
- 用
qr = qrcode.QRCode(version=1, box_size=10, border=4)显式控制尺寸,version范围 1–40,值越大容数据越多但图越密 -
box_size=10表示每个“黑块”是 10×10 像素,太小(如 2)在高清屏上糊成一片,太大(如 50)导致图臃肿 -
border=4是四周留白格子数,设为 0 会扫不出——多数扫码器要求至少 4 格空白
响应头 Cache-Control 要谨慎设
二维码内容若带动态参数(比如用户 token),必须禁用缓存,否则 CDN 或浏览器可能复用旧图。
- 用
send_file(..., as_attachment=False, download_name=None)配合make_response()手动加头:response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" - 纯静态内容(如固定网址)可设
max-age=31536000,但注意 Flask 默认不带 ETag,强缓存后更新难感知 - 别漏掉
as_attachment=False,否则浏览器强制下载,而不是内联显示
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











