在Python Flask服务器上使用fileddrop .js上传文件

Upload files with FileDrop.js on a Python Flask server

本文关键字:fileddrop js 文件 Python Flask 服务器      更新时间:2023-09-26

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

这样做的原因似乎是Flask希望通过POST将文件发送到服务器,并附带一个用于从应用程序识别文件的附加参数。我使用了另一个文件上传框架jQuery fileddrop:

<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'

然而,我怎么能得到我上传的文件使用fileddrop .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访问它。有什么建议吗?

我实际上正在研究同样的问题,也许可以帮助你与我所确定的。

首先,只有当数据从使用特定编码和类型的表单发送时,flask请求上的files属性才会出现。FileDrop不使用这个,所以请求中的files属性应该是空的。

标记用enctype=multipart/form-data标记,并以该形式放置an。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()

这只是一个例子,但它是有效的。显然,您仍然应该遵循我所链接的flask"文件上传"页面上的安全提示,以确保文件名的安全,但除此之外,这就是它的全部内容。

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