用于下载 Python3 Flask 生成的 Zip 文件的 Javascript 按钮

Posted

技术标签:

【中文标题】用于下载 Python3 Flask 生成的 Zip 文件的 Javascript 按钮【英文标题】:Javascript Button to Download ZipFile Generated by Python3 Flask 【发布时间】:2019-12-03 17:59:43 【问题描述】:

我在 Ubuntu 18.04 上使用 Python 3.7 生成一个 ZipFile,并使用 Flask 1.0.2 提供它。我知道 Flask 代码有效,因为我可以在浏览器中显式键入端点并获得可以在 Windows 10 上解压缩的有效 ZipFile。我现在正试图让我的 javascript 代码通过单击按钮下载 ZipFile。问题是生成的文件被 Windows 声明为“损坏”并且无法解压缩。如何让 Javascript 正确下载文件?

Flask 代码如下所示:

@app.route("/get_new_training_data", methods=["GET"])
def create_and_serve_training_data_zipfile():

    # Define the location of the new training data
    newDataLocation = "%s" % (configuration.NEW_TRAINING_DATA_LOCATION)

    # Ensure it exists or throw and error
    if os.path.isdir(newDataLocation):

        print("[%s] Creating new ZipFile for download from: %s" % (os.path.basename(__file__), newDataLocation))

        # Create a zipfile in memory and send it back to the user
        # The zipfile will contain the training data collected through
        # the webbrowser button controls
        try:

            memoryFile = BytesIO()
            with zipfile.ZipFile(memoryFile, 'w', zipfile.ZIP_DEFLATED) as zf:
                for root, dirs, files in os.walk(newDataLocation):
                    for file in files:
                        print("[%s] Adding file to ZipFile: %s" % (os.path.basename(__file__), file))
                        zf.write(os.path.join(root, file))
            memoryFile.seek(0)
            return send_file(memoryFile, mimetype='application/zip', attachment_filename='ImageData.zip', as_attachment=True)

        except Exception as err:

            newStatus = "download_image_data": "Failed: Error Could not create Zipfile: %s"%(err)

            print("[%s] Error downloading new Training Data - JSON Response is: %s" % (
            os.path.basename(__file__), newStatus))

            return jsonify(newStatus), 500

    else:

        newStatus = "download_image_data": "Failed: Error Training Data directory does not exist"

        print("[%s] Error downloading new Training Data - JSON Response is: %s" % (os.path.basename(__file__), newStatus))

        return jsonify(newStatus), 500

Javascript 代码在这里:

// Add an on click for the download data button
var downloadTrainingDataButton = document.getElementById("downloadTrainingData");
downloadTrainingDataButton.onclick = function() 

    console.log("Downloading New Training Data ...");

    // Do a web request to download a zip file of the training data
    var logRequestXmlHttp = new XMLHttpRequest();
    logRequestXmlHttp.open( "GET", "http://host_ip/get_new_training_data", true ); // false for synchronous request
    logRequestXmlHttp.onload = function(e) 
        code = logRequestXmlHttp.response;

        if (logRequestXmlHttp.status == 200) 

            var blob = new Blob([this.response], type: "application/zip");
            var url = window.URL.createObjectURL(blob);
            var link = document.createElement('a');
            document.body.appendChild(link);
            link.style = "display: none";
            link.href = url;
            link.download = "ImageData.zip";
            link.click();

            setTimeout(() => 
            window.URL.revokeObjectURL(url);
            link.remove();  , 100);

            console.log("Success downloading zip file");

        

    ;
    logRequestXmlHttp.onerror = function () 
        console.log("Error with downloading zip file: " + logRequestXmlHttp.responseText + " Code: " + code);
    ;
    logRequestXmlHttp.send( null );


谢谢。

【问题讨论】:

而不是像你一样使用 js。仅在锚点上使用下载属性怎么样? <a href="http://host_ip/get_new_training_data" download="training_data.zip">Download Training Data</a>developer.mozilla.org/en-US/docs/Web/html/Element/a#download 您是否有理由希望通过烧瓶提供 zip 文件,而不是简单地将其作为磁盘中的静态文件提供给 Web 服务器?将其全部加载到内存中可能会成为性能瓶颈。 @dmitrybelyakov 我希望 JS 中的按钮能够动态生成 zipfile,因为它的潜在内容可能会非常频繁地变化。 @AndrewLohr 请发表您的评论和回答。它对我有用!我会选择你的答案 - 谢谢。 确定@PhilBot 很高兴它对你有用。 【参考方案1】:

要下载文件,您可以使用锚标记上的HTML5 download attribute 让它知道它需要下载资源而不是导航到它。这可能是实现您想要的最简单的方法。

例如:

<a href="http://host_ip/get_new_training_data" download="training_data.zip">Download Training Data</a>

【讨论】:

以上是关于用于下载 Python3 Flask 生成的 Zip 文件的 Javascript 按钮的主要内容,如果未能解决你的问题,请参考以下文章

pdb文件是啥?

Flask - flask-script | 多app应用 | wtforms

python3-开发进阶Flask的基础

Flask 安装第三方库 ImportError: No module named flask 导包失败,Python3重新安装Flask模块

从 Dash/Flask 应用程序下载动态生成的文件

flask2