如何将来自微服务的响应转发回客户端?

How do I forward responses from microservices back to the client?

TL/DR:在烧瓶端点内,我正在向另一个端点发出请求,我想 return 该请求的响应.回复是一个文件附件,我如何正确return那个回复? response.content 不会剪切(在浏览器中显示二进制文件而不是下载文件)


详情如下:


我一直在网上寻找此问题的解决方案,但我似乎找不到任何有相同问题的人,这可能表明我可能正在解决这个问题。这是细分:

我有一个后端 运行 一些 flask 微服务,其中之一是与前端交互的主要网关。我的应用程序的一部分涉及用户访问特定的 link,即 return 文件下载。通过一些研究,我发现使用 send_file()send_from_directory() 在 Flask 中执行此操作非常简单。我面临的问题是,我已将所有与文件存储相关的 activity 放入其自己的微服务中,但我无法弄清楚如何将从该微服务获得的响应“转发”回客户端网关。

所以本质上,我有:

filestorage_service:app.py:

# flask stuff: imports, app config, etc

@app.route('/get', methods=['GET'])
def get_file():
    filename = request.form.get('filename')

    try:
        return send_from_directory("<some_base_dir>", filename=filename, as_attachment=True)

    except FileNotFoundError:
        return "Error: File not found", 400

网关:app.py:

# flask stuff: imports, app config, etc

@app.route('/get-file/<filename>', methods=['GET'])
@cross_origin()
def get_file(filename):
    data = {
        'filename': filename
    }

    res = requests.get("<filestorage_service_url>" + "/get", data=data)
    
    # now what??
    

我该如何 returning res?简单地放置 return res 会出错,而 returning res.content 实际上会在浏览器中显示图像二进制文件。我应该进入完全代理模式并从头开始重建整个响应,还是我缺少更简单的方法?

我设法获得了您的应用程序的精简版来执行您想要的操作。

import os

import requests
from flask import Flask, send_from_directory, Response

app = Flask(__name__)

# Storage service
@app.route('/get', methods=['GET'])
def get_file():
    filename = 'somefile.txt'

    try:
        return send_from_directory(os.getcwd(), filename=filename, as_attachment=True)

    except FileNotFoundError:
        return "Error: File not found", 400

# Front end
@app.route('/getfile', methods=['GET'])
def get_file_1():
    res = requests.get("http://127.0.0.1:5000" + "/get",)  # call storage
    return Response(
        res.content,  # content fromthe storage service has the file data
        headers=dict(res.headers)  # headers need to copied to start download
    )


app.run(debug=True)

您需要做的就是确保内容 & headers 是从您要转发的回复中复制的。重要的 headers 是 Content-DispositionContent-TypeContent-Length headers。文件内容本身在 response.content