调用send_file()时返回文本文档而不是imag

2024-10-02 12:23:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我想从服务器端发送一个图像文件到客户端。我用的是烧瓶框架。在

但问题是每当我调用send_file()所在的路由时,响应返回的是一个文件。当我单击此文件时,gedit打开它,文件中没有任何内容。这意味着它必须是文本文件写的。在

我参考了烧瓶文档中的^{}。在

以下是我在代码中所做的:

@app.route('/try')
def trial():
    todown = 'https://igcdn-photos-e-a.akamaihd.net//hphotos-ak-xaf1//t51.2885-15//e35//12093691_1082288621781484_1524190206_n.jpg'  
    resp = requests.get(todown)
    return send_file(resp,mimetype="image/jpeg",attachment_filename="img.jpg",as_attachment=True)

每当我加载localhost:5000/try时,都会下载一个文件,但不是要下载的图像文件。在

我在终端中得到的错误是AttributeError: 'Response' object has no attribute 'read' error。在

一定是什么问题。上面的片段中有什么遗漏吗?在


Tags: 文件框架send客户端路由attachment烧瓶图像文件
1条回答
网友
1楼 · 发布于 2024-10-02 12:23:02
  1. resprequests.models.Response对象,不是字符串也不是字节:

    >>> import requests
    >>> todown = 'https://igcdn-photos-e-a.akamaihd.net//hphotos-ak-xaf1//t51.2885-15//e35//12093691_1082288621781484_1524190206_n.jpg'
    >>> resp = requests.get(todown)
    >>> resp
    <Response [200]>
    >>> type(resp)
    <class 'requests.models.Response'>
    
  2. Flask.send_file()发送一个文件


所以首先需要使用resp.content来获取对象的内容,它将返回bytes对象(顺便说一下,resp.text返回string对象。 如果要下载图像、视频或其他非文本内容,请始终使用.content)。在

^{pr2}$

有关详细信息,请查看the document。在


然后,因为Flask.send_file()发送了一个文件,所以您需要在发送之前将该图像写入一个文件。在

但由于您不需要在服务器上使用此映像,因此我建议在本例中使用^{},因此您不需要在发送后删除该映像。注意,如果发送文本文件,请使用^{}。在

例如:

import requests
from io import BytesIO
from flask import Flask, send_file

app = Flask(__name__)

@app.route('/')
def tria():
    todown = 'https://igcdn-photos-e-a.akamaihd.net//hphotos-ak-xaf1//t51.2885-15//e35//12093691_1082288621781484_1524190206_n.jpg'
    resp = requests.get(todown)
    return send_file(BytesIO(resp.content), mimetype="image/jpeg", attachment_filename="img2.jpg", as_attachment=True)

app.run(port=80, debug=True)

但是,如果您想将图像写入一个文件并随后发送,请确保您也可以这样做。我们可以使用^{}来创建一个tempfile,而不是仅仅创建一个文件来避免重写重要的文件。在

从文件中:

This function operates exactly as TemporaryFile() does, except that the file is guaranteed to have a visible name in the file system (on Unix, the directory entry is not unlinked).

That name can be retrieved from the name attribute of the file object. Whether the name can be used to open the file a second time, while the named temporary file is still open, varies across platforms (it can be so used on Unix; it cannot on Windows NT or later). If delete is true (the default), the file is deleted as soon as it is closed.

The returned object is always a file-like object whose file attribute is the underlying true file object. This file-like object can be used in a with statement, just like a normal file.

例如:

import tempfile
import requests
from flask import Flask, send_file

app = Flask(__name__)


@app.route('/')
def tria():
    todown = 'https://igcdn-photos-e-a.akamaihd.net//hphotos-ak-xaf1//t51.2885-15//e35//12093691_1082288621781484_1524190206_n.jpg'

    resp = requests.get(todown)

    with tempfile.NamedTemporaryFile() as f:  
        # create a file-like object use `NamedTemporaryFile()` and `with` 
        # as the basic usage which said in the document     

        f.write(resp.content)
        # write the content of the image into it

        return send_file(f.name, mimetype="image/jpeg",
                         attachment_filename="img2.jpg", as_attachment=True)                             
        # `f.name` is the temp file's filename

app.run(port=80, debug=True)

相关问题 更多 >

    热门问题