如何使用 AJAX 调用和 Flask 上传 (csv) 文件
How to upload a (csv) file with an AJAX call and Flask
我正在更新一个使用 AJAX 并决定使用 Flask 的旧项目。对于我当前正在处理的特定页面,我需要能够上传 CSV 文件并读取文件中的数据(无需保存)。我还有其他几个使用 AJAX 工作的页面,但它们 return 将数据返回给 Flask(例如,它是什么学期,它是哪一年,等等)。理想情况下,我希望能够上传 CSV 文件并读取表单数据(我在下面调用的变量 formData
和 myFormData
)。
我找到了 this post 并基于它建立了我的 MWE,但是当我查看 request.files
时,我得到了一个空字典。这是我的代码:
run.py:
import os
from app import app
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port, debug=True)
__init__.py:
from flask import Flask, session
import flask_excel as excel
from fileUpload import fileUpload_bp
def create_app():
app = Flask(__name__, template_folder="templates")
app.secret_key = 'flask-ajax file upload test'
app.register_blueprint(fileUpload_bp)
excel.init_excel(app)
return app
app = create_app()
file_upload.py:
from flask import Flask, render_template, request, Blueprint
fileUpload_bp=Blueprint('fileUpload',__name__)
@fileUpload_bp.route('/fileUpload',methods=['GET','POST'])
def fileUpload():
if request.method=="POST":
print(request.files)
return render_template("fileUpload.html")
fileUpload.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>file upload test</title>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript"
src="static/scripts/fileUpload.js"></script>
</head>
<body>
<form action="javascript:fileUpload()" method="POST" enctype="multipart/form-data">
<input type="file" id="file_upload_data"><br>
<input type="text" id="form_data" value="sample data">
<button type="submit">Upload</button>
</form>
</body>
</html>
fileUpload.js:
function fileUpload()
{
var formData=new FormData($("file_upload_data")[0]);
var myFormData={form_data: $("#form_data").val()};
$.ajax({
type: 'post',
dataType: 'html',
url: 'fileUpload',
async: false,
data: formData,
contentType: false,
cache: false,
processData: false,
success: function (data){
console.log('Success');
},
error: function(response, status, xml) {
console.log('failure');
}
});
}
一些附加信息:这是一个更大项目的一部分,这就是我使用蓝图和 flask_excel 的原因。我看到人们建议使用 AJAX 以外的其他东西,但我正在尝试使用 Flask 将页面 运行 与 python3 一起使用,而不重写已经存在的所有内容。
为了序列化表单,输入字段必须具有名称属性。
我在下面的最小示例中使用了表单的提交事件。事件侦听器在文档完全加载时注册。提交表单时,表单数据被序列化并通过ajax.
发送
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Upload</title>
</head>
<body>
<form name="upload-form" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">Upload</button>
</form>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Register the listener for submit events.
$('form[name="upload-form"]').submit(function(evt) {
// Prevent the form from default behavior.
evt.preventDefault();
// Serialize the form data. The entire form is passed as a parameter.
const formData = new FormData($(this)[0]);
// Send the data via ajax.
$.ajax({
type: 'post',
url: '/upload',
data: formData,
contentType: false,
cache: false,
processData: false,
}).done(function(data) {
console.log('success');
}).fail(function(xhr, status, error) {
console.error('error');
});
});
});
</script>
</body>
</html>
server-side 代码基本保持不变。但是,出于清洁的原因,我建议您将 ajax 请求的端点与 return html.
请求的端点分开
from flask import Flask
from flask import make_response, render_template, request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload():
print(request.files)
return make_response('', 200)
我正在更新一个使用 AJAX 并决定使用 Flask 的旧项目。对于我当前正在处理的特定页面,我需要能够上传 CSV 文件并读取文件中的数据(无需保存)。我还有其他几个使用 AJAX 工作的页面,但它们 return 将数据返回给 Flask(例如,它是什么学期,它是哪一年,等等)。理想情况下,我希望能够上传 CSV 文件并读取表单数据(我在下面调用的变量 formData
和 myFormData
)。
我找到了 this post 并基于它建立了我的 MWE,但是当我查看 request.files
时,我得到了一个空字典。这是我的代码:
run.py:
import os
from app import app
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port, debug=True)
__init__.py:
from flask import Flask, session
import flask_excel as excel
from fileUpload import fileUpload_bp
def create_app():
app = Flask(__name__, template_folder="templates")
app.secret_key = 'flask-ajax file upload test'
app.register_blueprint(fileUpload_bp)
excel.init_excel(app)
return app
app = create_app()
file_upload.py:
from flask import Flask, render_template, request, Blueprint
fileUpload_bp=Blueprint('fileUpload',__name__)
@fileUpload_bp.route('/fileUpload',methods=['GET','POST'])
def fileUpload():
if request.method=="POST":
print(request.files)
return render_template("fileUpload.html")
fileUpload.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>file upload test</title>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript"
src="static/scripts/fileUpload.js"></script>
</head>
<body>
<form action="javascript:fileUpload()" method="POST" enctype="multipart/form-data">
<input type="file" id="file_upload_data"><br>
<input type="text" id="form_data" value="sample data">
<button type="submit">Upload</button>
</form>
</body>
</html>
fileUpload.js:
function fileUpload()
{
var formData=new FormData($("file_upload_data")[0]);
var myFormData={form_data: $("#form_data").val()};
$.ajax({
type: 'post',
dataType: 'html',
url: 'fileUpload',
async: false,
data: formData,
contentType: false,
cache: false,
processData: false,
success: function (data){
console.log('Success');
},
error: function(response, status, xml) {
console.log('failure');
}
});
}
一些附加信息:这是一个更大项目的一部分,这就是我使用蓝图和 flask_excel 的原因。我看到人们建议使用 AJAX 以外的其他东西,但我正在尝试使用 Flask 将页面 运行 与 python3 一起使用,而不重写已经存在的所有内容。
为了序列化表单,输入字段必须具有名称属性。
我在下面的最小示例中使用了表单的提交事件。事件侦听器在文档完全加载时注册。提交表单时,表单数据被序列化并通过ajax.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Upload</title>
</head>
<body>
<form name="upload-form" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">Upload</button>
</form>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Register the listener for submit events.
$('form[name="upload-form"]').submit(function(evt) {
// Prevent the form from default behavior.
evt.preventDefault();
// Serialize the form data. The entire form is passed as a parameter.
const formData = new FormData($(this)[0]);
// Send the data via ajax.
$.ajax({
type: 'post',
url: '/upload',
data: formData,
contentType: false,
cache: false,
processData: false,
}).done(function(data) {
console.log('success');
}).fail(function(xhr, status, error) {
console.error('error');
});
});
});
</script>
</body>
</html>
server-side 代码基本保持不变。但是,出于清洁的原因,我建议您将 ajax 请求的端点与 return html.
请求的端点分开from flask import Flask
from flask import make_response, render_template, request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload():
print(request.files)
return make_response('', 200)