Flask:如何处理application / octet-stream

时间:2013-04-12 22:08:23

标签: python flask

我想创建一个多文件上传表单。我使用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([])

  3. 我的第一个问题是:为什么AJAX请求和正常请求之间存在差异 我的第二个问题是:如何在application/octet-stream中处理此Flask/Python请求 我的第三个问题是:这是使用application/octet-stream的好方法吗?

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

2 个答案:

答案 0 :(得分:2)

我无法使用application/octet-stream类型的帖子获取请求,但过去曾使用multipart/form-data类型表单使用flask上传图片。

我已经扩展了我过去所做的工作,以支持多个上传文件,这可以利用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>

Flask App

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()

答案 1 :(得分:2)

无论数据编码如何,您都应该能够使用request.data获取原始数据。 对于application/octet-stream,您只需将request.data写入二进制文件即可。

An example handler for various data types

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 ;)"

处理表单数据的典型方案已经记录在案here