需要帮助理解Python Flask中的文件上传,w /和Javascript + Ajax

时间:2017-04-22 04:52:41

标签: javascript python ajax file-upload flask

我正在编写一个webapp,让用户上传照片,然后将有关这些照片的数据返回到前端以触发某些活动。

我开始使用我在网上找到的教程/指南here

然而,我发现这没有javascript工作,我感到非常惊讶。我不明白按下按钮如何发出请求,要求选择文件的弹出窗口。它是如何知道该按钮用于文件上传的?不在HTML的哪个地方我给它一个明显的属性,告诉它上传一个文件,而在python / Flask中我没有选择用于上传的按钮。

令我惊讶的是,我也注意到,在给出的示例中,路由必须被称为“/ upload”才能工作。同样,我无法看到任何定义的位置或我可以在哪里更改它。在该链接上使用的唯一文件(这是我的webapp的基础)是app.py和index.html(运行Web服务器似乎不需要setup.py文件)

随着我的webapp的进展,我尝试添加一个javascript文件,该文件将从/ uploads路由获取响应并将其显示在前端,但很快就遇到了麻烦。看来我只能从当前正在运行的任何神秘力量上运行/上传。我的javascript无法访问它,因此我无法将响应转换为JS,以便我可以按照我想要的方式在前端显示它。

有人可以帮我理解链接中文件上传服务器的工作原理,以便我可以修改它以使用我的JavaScript吗?

请注意,我的webapp基本上只是该链接中的程序,对上传的文件进行了大量分析。我在webapp的工作方式上所做的唯一改变是,不应该将您重定向到上传的文件,而是应该返回一个包含该文件信息的字符串。

我认为不值得发布我的python和HTML代码太多了,因为所有重要的东西都在那个链接中,但是javascript文件在下面。

    "use strict";

var main = function() {
    console.log("i am functioning!")

    var show_similar_img = function(){
        //Read megastatus
        $.ajax({
                method: "GET",
                url: "/upload",
                // contentType: 'application/json',
                dataType: "string"
        })
        .done(function(media_info){
            console.log(media_info)
        });
    }

    $("#upload-btn").on("click",function(){
        console.log("button pressed!")
        show_similar_img()
    })
}

console.log("i am being run!")
$(document).ready(main);

1 个答案:

答案 0 :(得分:1)

<input>元素的type属性为file,这就是浏览器知道如何以特定的方式处理它 - 正如您所注意到的那样,打开弹出模式窗口,提示用户选择文件。

路由必须称为上传,因为<form>元素的action属性值也称为上传。如果您还更改了表单的操作,则可以更改路径的名称。

由于File API,您实际上可以使用JavaScript访问文件信息(对于与input元素关联的文件)。 Mozilla开发者网络有一个很好的指南:https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

关于您的实际实施:首先,您还希望阻止您的表单提交在“常规”中进行处理。 (同步)方式,因此您需要在事件上调用preventDefault

$("#upload-btn").on("click",function(event) {
    event.preventDefault();
    console.log("button pressed!")
    show_similar_img()
 })

其次,我假设您要将文件实际发送到服务器(在Python / Flask上运行),因此您希望您的AJAX请求是POST而不是GET。因此,您需要修改show_similar_img,将请求作为POST发送,并使用前面提到的File API将文件包含在请求数据中。像这样:

var show_similar_img = function(){
    var formData = new FormData();
    var file = $("input[type='file']")[0].files[0];
    formData.append("file", file);

    $.ajax({
        url : "/upload",
        type : "POST",
        data : formData,
        contentType: false,
        processData: false
    })
    .done(function(media_info){
        console.log(media_info)
    });

}

编辑 - 我应该补充一点,我并不熟悉Flask或其request对象的复杂性。我假设无论文件是作为表单提交的一部分上传还是异步请求,它仍然可以在request.files['file']访问,但Flask可能无法在上面提供异步上传的文件。 request.files字典。但我非常确定该文件可以在request对象上的某处访问,因此您可能需要参考Flask文档。您还可以使用pdb在服务器端代码中添加断点,并检查request对象以查看它包含的内容(以及它保存的位置)。