在Python中重定向API服务器的下载文件

在Python中重定向API服务器的下载文件,python,flask,Python,Flask,我有两个服务器:一个用于API的后端,另一个作为web前端。 后端正在工作并提供以下文件: #API class for the route in Flask class DownloadDocument(Resource): def get(self): # accept the filename which must be downloaded in HTTP request. # That file is surely present in th

我有两个服务器:一个用于API的后端,另一个作为web前端。 后端正在工作并提供以下文件:

#API class for the route in Flask
class DownloadDocument(Resource):

    def get(self):

        # accept the filename which must be downloaded in HTTP request.
        # That file is surely present in the directory

        filename = request.headers.get('x-filename')      
       
        return send_from_directory(app.config['UPLOAD_FOLDER'], filename, as_attachment=True)
web前端当前以以下方式获取文件:

@app.route('/get_doc/<filename>')
@login_required
def get_doc(filename):
      sending = {'x-filename': filename}
      response = requests.get('http://<<api_server>>', headers=sending)
      return response.content
我不明白问题是在前端还是后端。 在前端,我尝试使用urllib.request.request或requests.request。 你知道如何管理这种下载吗?可能与mime解释、字节下载或本地缓冲有关。 当然,我不想在web前端存储中下载该文件。我想把它重定向到访问者

以下是GET的标题:

{'Content-Disposition': 'attachment; filename=20201116003_895083.jpg', 'Content-Length': '574424', 'Content-Type': 'image/jpeg', 'Last-Modified': 'Tue, 01 Dec 2020 14:04:30 GMT', 'Cache-Control': 'public, max-age=43200', 'Expires': 'Thu, 03 Dec 2020 02:34:51 GMT', 'ETag': '"1606831470.89299-574424-736697678"', 'Date': 'Wed, 02 Dec 2020 14:34:51 GMT', 'Server': 'Werkzeug/1.0.1 Python/3.8.3'}

我不确定这是否是构建应用程序的好方法。我认为Restful后端旨在使用Javascript前端,而不是一个单独的Flask应用程序,该应用程序将“后端”与请求库联系起来。我不确定这在更大的应用程序中会如何表现。例如,请求文档。在使用WSGI服务器部署时,您可能会看到一些不可预见的问题。国际海事组织

但是,考虑到这一点,实际问题的一个快速修复方法是使用flask.send_file函数返回文件。这将接受一个文件指针作为第一个参数,因此您需要使用io.BytesIO来转换bytes对象:

from flask import send_file
from io import BytesIO

@app.route('/get_doc/<filename>')
@login_required
def get_doc(filename):
      sending = {'x-filename': filename}
      response = requests.get('http://<<api_server>>', headers=sending)
      return send_file(BytesIO(response.content), mimetype='image/jpeg'
          #as_attachment=True
          )
您还需要提供mimetype参数,因为当像'file.jpg'这样的字符串作为第一个参数传递时,send_file通常会根据扩展名猜测mimetype。显然,在这种情况下,这是不可能做到的

如果希望用户收到下载提示,而不是在浏览器中查看图像,也可以传递为_attachment=True。这些都在报告中提到


再一次,这感觉像一个黑客。以这种方式使用请求库似乎有问题。也许其他SO用户可以对此发表进一步评论。

这个问题缺乏详细信息。在前端使用python请求库是不寻常的。您能否展示一个更大的代码示例,以演示如何将此文件导入浏览器?谢谢您的评论。我添加了更多的代码。是的,它成功了!我明白了。目前我必须使用这个解决方案,但我保证我会在将来改进它。非常感谢您的支持和快速回复!
from flask import send_file
from io import BytesIO

@app.route('/get_doc/<filename>')
@login_required
def get_doc(filename):
      sending = {'x-filename': filename}
      response = requests.get('http://<<api_server>>', headers=sending)
      return send_file(BytesIO(response.content), mimetype='image/jpeg'
          #as_attachment=True
          )