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

如何从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:53:20