我想创建一个多文件上传表单。我使用jQuery File Uploader。我的服务器端代码:
@app.route("/new/photogallery",methods=["POST"])
def newPhotoGallery():
print request.files
我尝试了两件事:
正常提交表格:
当我正常提交表格时,会打印出来:
ImmutableMultiDict([('post_photo_gallery', FileStorage: u'' ('application/octet-stream'))])
使用AJAX提交表单:
当我使用AJAX提交表单时,它会打印:
ImmutableMultiDict([])
我的第一个问题是:为什么AJAX请求和正常请求之间存在差异
我的第二个问题是:如何在application/octet-stream
中处理此Flask/Python
请求
我的第三个问题是:这是使用application/octet-stream
的好方法吗?
顺便说一句,我对application/octet-stream
了解不多。非常感谢你。
答案 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。