如何从Flask的GET响应中获取并显示GIF/PNG图片?
问题描述
我编写了一个Flask接口/getResults,通过send_file返回PNG图片(后续需支持1-5MB的GIF)。前端使用Axios发起GET请求,设置responseType为arraybuffer,尝试将响应转为base64后显示,但获取到的是二进制乱码,尝试多种方法均无效。请问Flask的send_file发送的是二进制数据吗?该如何正确获取并显示图片?
Flask代码
@app.route("/getResults", methods=['GET']) def get_results(): print(request) job_key = request.args["id"] filename = '/home/pat/projets/giftmaker/webapp/public/workingDir/1/test.png' return send_file(filename, mimetype='image/png')
前端代码
export function Download ({jobID}) { const [img, setImg] = useState(null); function test() { const params = new URLSearchParams([['id', jobID]]); axios.get('/getResults', {params}, {responseType: "arraybuffer"}) .then((response) => { setImg(Buffer.from(response.data, "binary").toString("base64")) }) .catch((e) => { console.log(e) }) }; return( <div> <button onClick={test}> Display </button> <img src={`data:image/png;base64,${img}`} /> </div> ) };
GET请求响应示例
�PNG � ��� IHDR���h���h�����������=�zTXtRaw profile type exif��xڥ�Y��6�m��Vd�H
解决方案
1. Flask的send_file确实发送二进制数据
send_file会读取文件的二进制内容,配合指定的Content-Type响应头返回。你当前代码里指定mimetype='image/png'是正确的,后续支持GIF时,要么把mimetype改成'image/gif',要么去掉该参数让Flask自动根据文件后缀推断MIME类型即可。
2. 前端代码的问题修复
你的前端代码存在两个核心问题:
- Axios参数格式错误:
axios.get的第二个参数是统一的配置对象,你把params单独作为第二个参数、responseType放在第三个参数,会导致responseType不生效,Axios默认以文本格式解析响应,所以出现乱码。 - 浏览器环境不支持
Buffer:Buffer是Node.js专属API,浏览器中无法直接使用,需要替换为浏览器原生的转换方法。
修复后的前端代码(推荐用URL.createObjectURL,效率更高):
import { useState, useEffect } from 'react'; import axios from 'axios'; export function Download ({jobID}) { const [imgUrl, setImgUrl] = useState(null); function loadImage() { const params = new URLSearchParams([['id', jobID]]); axios.get('/getResults', { params, responseType: 'arraybuffer' }) .then((response) => { // 创建Blob URL,适合大文件(如1-5MB的GIF) const blob = new Blob([response.data], { type: response.headers['content-type'] }); const url = URL.createObjectURL(blob); setImgUrl(url); }) .catch((e) => { console.error('加载图片失败:', e); }) }; // 组件卸载时释放Blob URL,避免内存泄漏 useEffect(() => { return () => { if (imgUrl) { URL.revokeObjectURL(imgUrl); } }; }, [imgUrl]); return( <div> <button onClick={loadImage}>显示图片</button> {imgUrl && <img src={imgUrl} alt="生成结果" />} </div> ) };
如果一定要用base64方式,替换then里的代码即可:
.then((response) => { const uint8Array = new Uint8Array(response.data); // 将Uint8Array转为字符串后再转base64 const base64Str = btoa(String.fromCharCode(...uint8Array)); setImgUrl(`data:${response.headers['content-type']};base64,${base64Str}`); })
3. 额外优化建议
- 对于1-5MB的GIF,优先用
URL.createObjectURL,因为base64会让文件体积膨胀约30%,加载效率更低。 - Flask端可自动推断MIME类型,适配多种图片格式:
import mimetypes @app.route("/getResults", methods=['GET']) def get_results(): job_key = request.args["id"] filename = '/home/pat/projets/giftmaker/webapp/public/workingDir/1/test.png' # 自动识别文件MIME类型 mime_type, _ = mimetypes.guess_type(filename) return send_file(filename, mimetype=mime_type)
内容的提问来源于stack exchange,提问作者Pat cm pro
相关产品推荐
相关产品推荐

