使用 Flask 和 jQuery 上传文件
Posted
技术标签:
【中文标题】使用 Flask 和 jQuery 上传文件【英文标题】:File upload using Flask and jQuery 【发布时间】:2017-04-10 22:45:19 【问题描述】:我在编写使用 jQuery 中的 ajax 调用发送 html 表单的程序时遇到问题。 这是我的 upload.html 和 form.js 文件:
$(document).ready(function()
$('form').on('submit', function(event)
$.ajax(
type : 'POST',
url : '/uploadhc',
data : $('#hc')
)
.done(function(data)
if (data.error)
$('#errorAlert').text(data.error).show();
$('#successAlert').hide();
else
$('#successAlert').text(data.file).show();
$('#errorAlert').hide();
);
event.preventDefault();
);
);
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<meta charset="UTF-8">
<title>File Upload</title>
<script type=text/javascript src=" url_for('static', filename='form.js') "></script>
</head>
<body>
<h1>Please upload all the corresponding files</h1>
<div id="upload">
<form id="upload-hc" >
<input type="file" name="file" accept=".csv" id="hc">
<input type="submit" value="go">
</form>
<br>
<p id="successAlert" style="display:none;">Success!</p>
<p id="errorAlert" style="display:none;">Fail!</p>
</div>
<script>
</script>
</body>
</html>
这是我的 Flask 服务器:
import os
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
@app.route("/")
def index():
return render_template("upload.html")
@app.route("/uploadhc", methods=['POST'])
def uploadhc():
target = os.path.join(APP_ROOT, "DataSource/")
if not os.path.isdir(target):
os.mkdir(target)
print request.files
if 'file' not in request.files:
error = "Missing data source!"
return jsonify('error': error)
file = request.files['file']
fileName = "DCData.csv"
destination = '/'.join([target, fileName])
file.save(destination)
success = "Success!"
return jsonify('file': success)
if __name__ == "__main__":
app.run(port=4555, debug=True)
当我尝试选择一个 csv 文件并提交 HTML 表单时,服务器说 request.files 是 ImmutableMultiDict([]),它是空的。知道如何将文件发送到我的服务器吗?谢谢!
【问题讨论】:
【参考方案1】:您需要将表单作为分段上传发送,您可以将整个表单转换为FormData(formElement)
var form = $('#upload-hc')[0]
var fd = new FormData(form)
$.ajax(
type : 'POST',
url : '/uploadhc',
data: fd,
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
)
如果你有兴趣,这里有一个 es6 版本
// short for jquery(function($) ... )
// which is the equvilant to $(document).ready(function($)
jQuery($ =>
$('form').on('submit', event =>
event.preventDefault()
let form = $('#upload-hc')[0]
let fd = new FormData(form)
fetch('/uploadhc', method: 'POST', body: fd)
.then(res =>
// console.log(res.ok)
return res.json() // or res.text, res.arraybuffer
)
.then(result =>
console.log(result)
)
)
)
【讨论】:
谢谢!我试过 FormData([formElement]),但是 ImmutableMultiDict([]) 还是空的 你试过没有[]
吗?
是的。但是我的服务器仍然无法获取表单数据【参考方案2】:
在html端:
<input type="file" id="uploadfile" name="NewCsvUpload">
在javascript方面:
var form_data = new FormData();
form_data.append('file', $('#uploadfile').prop('files')[0]);
$(function()
$.ajax(
type: 'POST',
url: '/uploadLabel',
data: form_data,
contentType: false,
cache: false,
processData: false,
success: function(data)
console.log('Success!');
,
)
);
在服务器端:
@app.route('/uploadLabel',methods=[ "GET",'POST'])
def uploadLabel():
isthisFile=request.files.get('file')
print(isthisFile)
print(isthisFile.filename)
isthisFile.save("./"+isthisFile.filename)
【讨论】:
【参考方案3】:当我过去这样做时,我总是将enctype="multipart/form-data"
放在form
div 中。
这里有几个链接可以更详细地解释它:
upload file inside a form html https://www.cs.tut.fi/~jkorpela/forms/file.html【讨论】:
是的。但我不认为添加“enctype”在这里有帮助。以上是关于使用 Flask 和 jQuery 上传文件的主要内容,如果未能解决你的问题,请参考以下文章