【问题标题】:Upload files with FileDrop.js on a Python Flask server在 Python Flask 服务器上使用 FileDrop.js 上传文件
【发布时间】:2015-06-01 13:14:17
【问题描述】:

我运行 Python Flask 应用程序并希望实现将文件上传到服务器的可能性。 FileDrop.js 看起来很有希望完成这项任务,但是,我不能让它与 Flask 一起工作。

原因似乎是 Flask 期望文件通过 POST 以及用于从应用程序中识别文件的附加参数发送到服务器。我使用另一个文件上传框架jQuery filedrop

<html>
<head>
<script type="text/javascript" src="https://github.com/weixiyen/jquery-filedrop/blob/master/jquery.filedrop.js"></script>
</head>
<body>

<fieldset id="zone">
    <br><br>
    <legend><strong>Drop one or more files inside...</strong></legend>
    <br><br>
</fieldset> 

        <script type="text/JavaScript">

            // when the whole document has loaded, call the init function
            $(document).ready(init);

            function init() {

                var zone = $('#zone'),
                    message = $('.message', zone);

                // send all dropped files to /upload on the server via POST
                zone.filedrop({
                    paramname: 'file',
                    maxfiles: 200,
                    maxfilesize: 20,
                    url: '/upload',
                }

            }

        </script>

</body>
</html>

paramname: 'file' 以某种方式随请求一起发送,以便在我的 Flask 应用程序中,我可以通过以下方式获取上传的文件:

@app.route('/upload', methods=['POST'])
def upload():

    if request.method == 'POST':
        file = request.files['file']
        file.save('myfile.ext')
        return 'Done'

但是,如何使用FileDrop.js 获取我上传的文件?我在文档中看不到如何通过 POST 传递附加参数的可能性。当我按照文档中的最小示例进行操作时,例如

<html>
<head>
<script type="text/javascript" src="https://github.com/ProgerXP/FileDrop/blob/master/filedrop.js"></script>
</head>
<body>

    <fieldset id="zone">
      <legend>Drop a file inside...</legend>
      <p>Or click here to <em>Browse</em>...</p>
    </fieldset>

        <script type="text/JavaScript">

            // when the whole document has loaded, call the init function
            $(document).ready(init);

            function init() {

                var options = {iframe: {url: '/upload'}}
                var zone = new FileDrop('zone')

                // Do something when a user chooses or drops a file:
                zone.event('send', function (files) {

                // FileList might contain multiple items.
                files.each(function (file) {

                // Send the file:
                file.sendTo('/upload')

                  })
                })

            }

        </script>

</body>
</html>

然后尝试在 Flask 中检查上传的文件:

@app.route('/uploadtest', methods=['POST'])
def uploadtest():

    print(request.files)

    return 'end'

request.files 现在是ImmutableMultiDict([]),我不知道如何从 Flask 访问它。有什么建议吗?

【问题讨论】:

    标签: javascript python flask filedrop.js


    【解决方案1】:

    我实际上正在解决同样的问题,也许可以帮助您解决我确定的问题。

    首先,flask 请求上的files 属性仅适用于使用特定编码和类型从表单发送数据时。 FileDrop 不使用它,因此请求中的files 属性应该为空。

    一个标签用 enctype=multipart/form-data 标记,一个放在那个表单中。 http://flask.pocoo.org/docs/0.10/patterns/fileuploads/

    FileDrop 似乎不像 dropzone.js 使用这种形式那样发送它。我所做的是查看 FileDrop 发出的网络请求。这是一个帖子。我可以看到它是作为一个帖子处理的。数据在哪里?在我的浏览器的网络请求中,我可以看到一个名为X-File-Name 的标头,它是正在上传的文件的 url 引用名称。我可以在请求对象中访问它。

    fileName = urlparse.unquote(request.headers['X-File-Name'])
    

    实际数据在哪里?它在 POST 请求的正文中。那是在request.data 中——无论以何种编码格式上传的整个文件。

    foo = open('/tmp/%s' % fileName, 'w')
    foo.write(request.data)
    foo.close()
    

    这只是一个示例,但它确实有效。显然,您仍然应该遵循我为保护该文件名而链接的烧瓶“文件上传”页面上的安全提示,否则就是这样。

    使用帖子正文的直接缺点是每个请求一个文件,但这对我的特定应用程序来说并不是什么大问题。希望有帮助。

    【讨论】:

    • 谢谢你。使files 属性仅在以多模式从表单发送时才存在,这是一种让我发疯的出乎意料的特定功能。或者也许我只是不太了解 Flask。不管怎样,你帮了我很大的忙。
    猜你喜欢
    • 1970-01-01
    • 2016-12-18
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    • 2021-11-07
    • 2018-05-20
    • 2013-12-28
    • 1970-01-01
    相关资源
    最近更新 更多