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

如何在同一个Flask接口中同时返回带自定义响应头的JSON信息与文件响应?

如何在同一个Flask接口中同时返回带自定义响应头的JSON信息与文件响应?

兄弟,你的问题我太懂了——Flask的视图函数本来就只能返回一个响应对象,你现在试图同时返回send_file的文件响应和jsonify的JSON响应,这肯定行不通,因为HTTP协议里一个请求对应一个响应,响应体只能有一份内容。不过我们有两种靠谱的解决办法,看你需求选:

方案一:把JSON信息放到自定义响应头里(推荐)

这是最常用的方式,因为文件响应的体已经被文件内容占了,没法同时塞JSON,所以把额外信息转成字符串放到自定义HTTP头里,前端拿到响应后读取这个头就能拿到你要的JSON数据,同时浏览器会自动处理文件下载。

修改你的代码如下:

from flask import Flask, send_file
import json

app = Flask(__name__)

@app.route('/download-pdf', methods=['GET'])
def download_pdf():
    file_path = 'Frame_relate.pdf'
    # 生成文件响应
    response = send_file(file_path, as_attachment=True, download_name="Frame_relate.pdf")
    
    # 设置自定义响应头:把JSON转成字符串放入头部
    additional_info = {"message": "File is being downloaded", "status": "success"}
    response.headers['X-Additional-Info'] = json.dumps(additional_info)
    
    # 其实Flask会自动根据响应情况设置状态码,你手动设的Status头可以去掉,或者用标准方式返回状态码
    # 如果一定要自定义状态相关的头,建议用标准的状态码字段,比如直接返回 (response, 200)
    return response

if __name__ == '__main__':
    app.run(debug=True)

解释一下:

  • 用json.dumps()把字典转成JSON字符串,放到自定义的X-Additional-Info头里(自定义头一般用X-前缀区分标准头)
  • 前端拿到响应后,读取response.headers.get('X-Additional-Info'),再解析成JSON就能拿到额外信息
  • 浏览器会正常触发文件下载,完全不影响

方案二:返回多部分(multipart)响应(不推荐,前端处理麻烦)

如果你的业务一定要把JSON和文件都放在响应体里,那得用multipart/form-data格式的响应,把JSON和文件作为两个不同的部分返回。这种方式需要手动构造多部分响应,前端也得专门解析,非常麻烦,一般只有特殊场景才用。

举个简单的例子(用Werkzeug的MultiPartResponse):

from flask import Flask
from werkzeug.wrappers import Response
from werkzeug.datastructures import MultiPartResponse, FileStorage
import json

app = Flask(__name__)

@app.route('/download-pdf', methods=['GET'])
def download_pdf():
    # 准备JSON部分
    json_data = json.dumps({"message": "File is being downloaded", "status": "success"}).encode('utf-8')
    json_part = Response(json_data, mimetype='application/json')
    
    # 准备文件部分
    file_path = 'Frame_relate.pdf'
    file_part = FileStorage(open(file_path, 'rb'), filename="Frame_relate.pdf")
    
    # 构造多部分响应
    multipart_response = MultiPartResponse([
        ('json', json_part),
        ('file', file_part)
    ])
    
    return multipart_response

if __name__ == '__main__':
    app.run(debug=True)

注意:这种方式前端不能直接触发浏览器下载,必须手动解析多部分内容,提取文件部分再创建下载链接,非常繁琐,所以优先选方案一。

备注:内容来源于stack exchange,提问作者RohithCodez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:29:50