12

我想制作一个多文件上传表单。我使用jQuery File Uploader。我的服务器端代码:

@app.route("/new/photogallery",methods=["POST"])
def newPhotoGallery():
    print request.files

我尝试了两件事:

  1. 正常提交表格:

    当我正常提交表单时,它会打印:

    ImmutableMultiDict([('post_photo_gallery', FileStorage: u'' ('application/octet-stream'))])

  2. 使用 AJAX 提交表单:

    当我使用 AJAX 提交表单时,它会打印:

    ImmutableMultiDict([])

我的第一个问题是:为什么 AJAX 请求和普通请求有区别。
我的第二个问题是:我如何处理这个application/octet-stream请求Flask/Python 我的第三个问题是:这是一种使用的好方法application/octet-stream吗?

顺便说一句,我不太了解application/octet-stream。非常感谢。

4

2 回答 2

2

我无法使用application/octet-stream类型帖子获得请求,但multipart/form-data过去曾使用类型表单使用烧瓶上传图像。

我已经扩展了我过去所做的工作以支持多个上传文件,这已经利用了 werkzeug 的FileStorage对象。

这里的关键是设置一个基于帖子的路由,该路由从表单中查找请求元素。这应该允许您通过标准表单或 AJAX 调用 POST 到路由。

下面是一个使用表单的简化示例:

视图模板:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>jQuery File Upload Example</title>
</head>
<body>
{% if err %}
    <h4>{{ err }}</h4>
{% endif %}

<form action="/" method=POST enctype=multipart/form-data id="fileupload">
    <input type="file" name="files" data-url="/" multiple>
    <input type=submit value=Post>
</form>

{% if files %}
{% for file in files %}
<p>Uploaded: <b>{{ file }}</b> </p>
{% endfor %}
{% endif %}
</body> 
</html>

烧瓶应用

from flask import Flask, request, render_template
from werkzeug import secure_filename, FileStorage
import os

# Flask functions
app = Flask(__name__) 
app.config.from_object(__name__)
DEBUG = True 
# add this so that flask doesn't swallow error messages
app.config['PROPAGATE_EXCEPTIONS'] = True

@app.route('/', methods=['GET', 'POST'])
def uploader():
    if request.method =='POST' and request.files.getlist('files'):
        up_file_list = []

        # Iterate the through a list of files from the form input field
        for a_file in request.files.getlist('files'):
            if a_file.filename:
                # Validate that what we have been supplied with is infact a file
                if not isinstance(a_file, FileStorage):
                    raise TypeError("storage must be a werkzeug.FileStorage")
                # Sanitise the filename
                a_file_name = secure_filename(a_file.filename)
                # Build target
                a_file_target = os.path.join('/tmp/', a_file_name)
                # Save file 
                a_file.save(a_file_target)
                up_file_list.append(a_file_name)
        # Return template
        if up_file_list:
            return render_template('uploader.html', err=None, files=up_file_list)
        else:
            return render_template('uploader.html', err='No Files Uploaded', files=None)
    else:
        return render_template('uploader.html', err=None, files=None) 


# application execution 
if __name__ == '__main__': 
    app.run()
于 2013-07-14T10:17:08.187 回答
2

无论数据编码如何,您都应该能够使用request.data. 在 的情况下application/octet-stream,您可以只写入request.data二进制文件。

各种数据类型的示例处理程序

from flask import json

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

    if request.headers['Content-Type'] == 'text/plain':
        return "Text Message: " + request.data

    elif request.headers['Content-Type'] == 'application/json':
        return "JSON Message: " + json.dumps(request.json)

    elif request.headers['Content-Type'] == 'application/octet-stream':
        with open('/tmp/binary', 'wb') as f:
            f.write(request.data)
            f.close()
        return "Binary message written!"

    else:
        return "415 Unsupported Media Type ;)"

处理表单数据的典型场景已在此处记录。

于 2018-03-13T06:10:20.560 回答