javascript 使用Flask和JS从服务器下载文件

fivyi3re  于 2023-06-28  发布在  Java
关注(0)|答案(3)|浏览(151)

当用户单击特定按钮时,我正在尝试下载文件。此文件是按下所述按钮时创建的图像。我想要的是,它应该自动下载客户端设备上的图像。
我在服务器代码上使用了Flask,理想情况下,Flask的send_file函数应该会触发这个自动下载,因为它添加了Content-Disposition头。
在客户端,我有一个JS代码,它使用fetch API向服务器发送一个POST请求,其中包含一些数据,用于生成要下载的图像。
这是JS代码:

function make_image(text){
    const json={
        text: text
    };
    const options={
        method: "POST",
        body: JSON.stringify(json),
        headers:{
            'Content-Type':'application/json',
        }
    };

    fetch('/image',options)
        .then(res=>{
            res.json(); //Gives an error: Uncaught (in promise) SyntaxError: Unexpected token � in JSON at position 0
        }).catch(err=>console.log(err));
}

这是服务器上的Python代码:

@app.route('/image',methods=['POST'])
def generate_image():
    cont = request.get_json()
    t=cont['text']
    print(cont['text'])
    name = pic.create_image(t)
    time.sleep(2)
    return send_file(f"{name}.png",as_attachment=True,mimetype="image/png")

但什么都没发生。图像无法下载。但是,映像是在服务器上创建的,没有损坏
我该如何解决这个问题?有没有其他方法来做我想做的事情?

xiozqbni

xiozqbni1#

你可以做下面的

return send_from_directory(dir, file_name, as_attachment=True)

这将在用户的机器上下载文件。
编辑:
顺便说一句,如果你创建一个像下面这样的html表单,你不需要JavaScript。

<form action='action here' method='post'>
    <input type='submit'>
</form>
nle07wnf

nle07wnf2#

由于@clockwatcher提到了一个不同的question,我使用了download.js模块来处理图像的下载。
所以我的JS代码现在看起来像这样:

function make_image(text){
    const json={
        text: text
    };
    const options={
        method: "POST",
        body: JSON.stringify(json),
        headers:{
            'Content-Type':'application/json',
        }
    };

    fetch('/image',options)
        .then(res=>{
            return res.blob();
        }).then(blob=>{
            download(blob)
        }).catch(err=>console.log(err));
}

在html中添加script标签:
<script src="https://cdnjs.cloudflare.com/ajax/libs/downloadjs/1.4.8/download.min.js"></script>
Python服务器代码没有任何变化。
它现在起作用了

whitzsjs

whitzsjs3#

代码中的错误在JavaScript中从Python服务器发送的响应是一个文件

return send_file(f"{name}.png",as_attachment=True,mimetype="image/png")

但是,您正在使用json()方法将响应(文件)转换为JSON

...

    fetch('/image',options)
        .then(res=>{
            res.json(); // **
        }).catch(err=>console.log(err));

您希望做的是使用blob()方法在响应上以blob形式接收文件,如下所示
在你的JS中

...

    fetch('/image',options)
        .then(res=>{
            res.blob(); // this returns the requested file as a blob/image file
        }).catch(err=>console.log(err));

相关问题