Flask如何发送gzip压缩图片并让浏览器自动解压显示?
问题分析与修复
你的新代码有几个关键问题导致无法正常工作,直接调整以下几点就能解决:
send_file不能直接传入字节数据:send_file需要接收类文件对象或文件路径,直接传压缩后的字节串会报错,得用BytesIO把字节数据包装成类文件对象。- 错误的附件配置:
as_attachment=True和download_name会强制浏览器将文件下载,而非直接显示,必须移除这两个参数。 - 缺少压缩编码响应头:浏览器要自动解压gzip内容,必须在响应头里添加
Content-Encoding: gzip,否则浏览器会把压缩后的字节当成普通图片数据处理,自然无法正常显示。
修正后的代码
from flask import Flask, request, send_file import gzip from io import BytesIO import os @app.route('/getLogImage/') def getLogImage(): try: # 过滤文件名,防止路径遍历攻击 fileName = os.path.basename(request.args.get('fn', '')) if not fileName: return "文件名参数缺失", 400 # 读取原图片文件 with open(f"D:/images/{fileName}", 'rb') as file: image_data = file.read() # gzip压缩图片数据 compressed_image_data = gzip.compress(image_data, 9) # 用BytesIO包装压缩后的数据 compressed_io = BytesIO(compressed_image_data) compressed_io.seek(0) # 将文件指针移到开头 response = send_file( compressed_io, mimetype='image/jpeg' ) # 添加编码头,告诉浏览器这是gzip压缩内容 response.headers['Content-Encoding'] = 'gzip' # 可选:告知浏览器压缩后的文件大小 response.headers['Content-Length'] = str(len(compressed_image_data)) return response except FileNotFoundError: return "图片文件不存在", 404 except Exception as err: return str(err), 500
额外优化提示
- JPEG本身已是压缩格式,gzip能带来的压缩率可能很低,甚至会让文件变大。可以考虑将图片转成WebP、AVIF这类更高效的格式,或者提前在服务器端压缩好图片,避免每次请求实时压缩消耗CPU。
- 始终对用户传入的文件名做过滤,防止恶意路径遍历攻击,上面代码里的
os.path.basename就是做这个用途。
内容的提问来源于stack exchange,提问作者sharkyenergy
相关产品推荐
相关产品推荐

