在烧瓶中接收 json 转换并形成数据
receive in flask json converted and form data
我有一个 API 装在烧瓶里。目标是接收转换后的 csv 文件(javascript 中的函数)并在 flask 中单独形成数据。表单数据是元数据,转换为 json 的 csv 文件是数据。
我只得到表单数据,json 文件我得到 none.
我的 json 从 csv 文件转换而来,它存储在变量结果中,表单数据存储在 formdata 中。我将两个变量分开发送。我收到了我在 HTML 中插入的所有数据。将 csv 文件转换为 json 的函数产生的 JSON 我没有进入 flask 端。
HTML
<!DOCTYPE html>
<html lang="PT">
<head>
<meta charset="utf-8">
<title>Register</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="/static/sendform.js"> </script>
<link href="{{url_for('static', filename='css/mainpage.css')}}" rel="stylesheet" type="text/css">
</head>
<body>
<div id="upper_left"></div>
<div id="upper_right"></div>
<div id="lower_left"></div>
<div id="lower_right"></div>
<div class="container">
<div class="title">Metadados - Dados relacionados com o Atleta</div>
<form action="index" method="post">
<div class="user-details">
<div class="input-box">
<span class="details">Nome Completo</span>
<input type="text" name="fullName" placeholder="Introduza o nome completo do atleta">
</div>
<div class="input-box">
<span class="details">Data de Nascimento</span>
<input type="text" name="birthdate" placeholder="Introduza a data de nascimento do atleta">
</div>
<div class="input-box">
<span class="details">Altura</span>
<input type="text" name="height" placeholder="Introduza a altura do atleta em cm">
</div>
<div class="input-box">
<span class="details">Peso</span>
<input type="text" name="weight" placeholder="Introduza o peso do atleta em kg">
</div>
<div class="input-box">
<span class="details">Tamanho da Piscina</span>
<input type="text" name="poolsize" placeholder="Introduza o tamanho da piscina">
</div>
<div class="input-box">
<span class="details">Modalidade</span>
<input type="text" name="modality" placeholder="Introduza a modalidade">
</div>
<div class="input-box">
<span class="details">Estilo(s) de Natação</span>
<input type="text" name="swimStyle" placeholder="Introduza o estilo(s) de natação">
</div>
<div class="input-box">
<span class="details">Género</span>
<select name="gender">
<option value ="gender">Selecionar genéro</option>
<option value ="masculino">Masculino</option>
<option value ="feminino">Feminino</option>
</select>
<div class="input-box">
<span class="details">Escalão Etário</span>
<select name="gender-title">
<option value ="gender-title">Select gender group</option>
<option value ="Escola_de_natacao">ESCOLA DE NATACAO</option>
<option value ="grupos_de_natacao_desportiva">GRUPOS DE FORMACAO DESPORTIVA</option>
<option value ="cadeteA">CADETES A</option>
<option value ="cadeteB">CADETES B</option>
<option value ="infatilB">INFANTIS B</option>
<option value ="infatilA">INFANTIS A</option>
<option value ="juvenilB">JUVENIS B</option>
<option value ="juvenilA">JUVENIS A</option>
<option value ="junior">JUNIORES</option>
<option value ="senior">SENIORES</option>
</select>
</div>
<div class="title">Metadados Envio de dados</div>
<div class="input-box">
<span class="details">Utilizador Id</span>
<input type="text" name="userId" placeholder="Introduza o seu Id">
</div>
<div class="input-box">
<span class="details">Token</span>
<input type="text" name="token" placeholder="Introduza o token">
</div>
<p>Selecionar o ficheiro localmente:</p>
<input name="myFile" type="file" accept=".txt,.xlsx, .xls, .csv" >
<div class="button">
<input type="submit" id="btn-post" value="Enviar dados" onclick="do_ajax();">
<div class="input-box"></dix>
</div>
</div>
</form>
</div>
</body>
</html>
Javascript
function do_ajax() {
var input = document.querySelector('input').files;
if(!input.length){
alert("No file selected");
return;
}
var file = input[0];
var reader = new FileReader();
reader.onload = (function() {
return function(e) {
var fileData = e.target.result.trim().split('\n').map(row => row.split(','));
var HEADERS = ["time", "yaw", "pitch", "roll", "heading", "ax", "ay", "az", "gx", "gy", "gz", "mx", "my", "mz"];
const RESULT = {};
// Assign every heading to the result.
for (const HEADING of HEADERS) RESULT[HEADING] = [];
fileData.map(row =>
// Each row → each column, number of columns === number of headers
row.map((column, i) =>
RESULT[HEADERS[i]]
.push(Number(column))
));
console.log(RESULT);
};
})(file);
reader.readAsText(file);;
let fullName = document.getElementById('fullName').value;
let birthdate = document.getElementById('birthdate').value;
let height = document.getElementById('height').value;
let weight = document.getElementById('weight').value;
let poolsize = document.getElementById('poolsize').value;
let modality = document.getElementById('modality').value;
let swimStyle = document.getElementById('swimStyle').value;
var tel = document.getElementById('gender').value;
var sel = document.getElementById('gender-title').value;
console.log(sel.value);
const formdata = new FormData();
formdata.append("fullName", fullName)
formdata.append("birthdate",birthdate)
formdata.append("weight",weight)
formdata.append("height",height)
formdata.append("poolsize",poolsize)
formdata.append("modality",modality)
formdata.append("swimStyle",swimStyle)
formdata.append("gender",tel)
formdata.append("gender-title",sel)
var xhr = new XMLHttpRequest();
xhr.open('POST', '/index', true);
xhr.send(formdata);
xhr.send(JSON.stringify(RESULT));
};
FLASK
from flask import Flask, request, render_template
import pymongo
import json
app = Flask(__name__)
app.debug = True
@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
def index():
if request.method == "POST":
name = request.form["fullName"]
birthdate =request.form["birthdate"]
poolsize =request.form["poolsize"]
height =request.form["height"]
weight =request.form["weight"]
modality =request.form["modality"]
swimStyle =request.form["swimStyle"]
gender = request.form["gender"]
gender_title = request.form["gender-title"]
output = request.get_json()
print(output)
print (name,birthdate,poolsize,height,weight,modality,swimStyle)
alldata = { "sessionData": output,
"metadata":{ "birthdate": birthdate, "Name": name,
"Weight": height,"Pool_size":poolsize,
"Weight":weight,"Gender":gender,"Gender_title":gender_title,
"modality":modality, "swimStyle": swimStyle}}
return alldata,200
else:
return render_template('index.html')
if __name__ == "__main__":
app.run()
一次数据传输只能符合一种格式。此格式是表单的编码或对应于 JSON 格式。
您仍然可以在一个请求中发送数据。
您可以将 JSON-formatted 数据作为字段添加到表单中,或者将表单数据转换为 JSON 结构。
对于第一个变体,需要在服务器端手动读取 JSON 数据。您可以为此使用 python json 库。对于后者,框架会完成这项工作。
第三种选择是在表单中传输文件并在服务器端读取它。
无论您选择哪个选项,都不要忘记验证输入。
在下面的示例中,所有表单数据都被转换为JSON并发送到服务器。为了清楚起见,我稍微缩短了代码。
表单数据添加JSON格式数据的版本应该是self-explanatory.
我认为最好的解决方案是读取文件服务器端。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Read CSV to JSON</title>
</head>
<body>
<form name="my-form" method="post" enctype="" enctype="multipart/form-data">
<input type="text" name="name" />
<!-- ... -->
<input type="file" name="csv" allow="text/csv" />
<input type="submit" />
</form>
<script type="text/javascript">
((uri) => {
function readCSV(file, delim=',') {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onerror = reject;
reader.onload = (evt) => {
resolve(evt.target.result.split(/\r\n|\n/).map(line => line.split(delim)));
};
reader.readAsText(file);
});
}
function serialize(formData) {
const data = {};
for (const [k, v] of formData) data[k] = v;
return data;
}
// Register a listener for submit events and suppress the default behavior of the form.
const form = document.querySelector('form[name="my-form"]');
form.addEventListener('submit', async evt => {
evt.preventDefault();
if(!evt.target.csv.files.length) {
alert('No file selected.');
return;
}
const file = evt.target.csv.files[0];
const formData = new FormData(evt.target);
formData.delete('csv');
// Conversion of the form data into an object.
const data = serialize(formData);
// Reading and converting the file into a list of objects.
// Adding the list to the previous object.
data['csv'] = await readCSV(file, ',')
.then(csv => {
const head = ['time', 'yaw', 'pitch', 'roll', 'heading', 'ax',
'ay', 'az', 'gx', 'gy', 'gz', 'mx', 'my', 'mz'];
return csv.map(row => {
let r = {};
row.forEach((col, i) => r[head[i]] = Number(col));
return r;
});
});
// Sending the JSON data to the server.
fetch(uri, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(resp => resp.json())
.then(data => console.log(data));
});
})({{ url_for('.data') | tojson }});
</script>
</body>
</html>
from flask import Flask
from flask import (
jsonify,
render_template,
request,
)
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/data', methods=['POST'])
def data():
data = request.json
print(data)
return jsonify(success=True)
我有一个 API 装在烧瓶里。目标是接收转换后的 csv 文件(javascript 中的函数)并在 flask 中单独形成数据。表单数据是元数据,转换为 json 的 csv 文件是数据。 我只得到表单数据,json 文件我得到 none.
我的 json 从 csv 文件转换而来,它存储在变量结果中,表单数据存储在 formdata 中。我将两个变量分开发送。我收到了我在 HTML 中插入的所有数据。将 csv 文件转换为 json 的函数产生的 JSON 我没有进入 flask 端。
HTML
<!DOCTYPE html>
<html lang="PT">
<head>
<meta charset="utf-8">
<title>Register</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="/static/sendform.js"> </script>
<link href="{{url_for('static', filename='css/mainpage.css')}}" rel="stylesheet" type="text/css">
</head>
<body>
<div id="upper_left"></div>
<div id="upper_right"></div>
<div id="lower_left"></div>
<div id="lower_right"></div>
<div class="container">
<div class="title">Metadados - Dados relacionados com o Atleta</div>
<form action="index" method="post">
<div class="user-details">
<div class="input-box">
<span class="details">Nome Completo</span>
<input type="text" name="fullName" placeholder="Introduza o nome completo do atleta">
</div>
<div class="input-box">
<span class="details">Data de Nascimento</span>
<input type="text" name="birthdate" placeholder="Introduza a data de nascimento do atleta">
</div>
<div class="input-box">
<span class="details">Altura</span>
<input type="text" name="height" placeholder="Introduza a altura do atleta em cm">
</div>
<div class="input-box">
<span class="details">Peso</span>
<input type="text" name="weight" placeholder="Introduza o peso do atleta em kg">
</div>
<div class="input-box">
<span class="details">Tamanho da Piscina</span>
<input type="text" name="poolsize" placeholder="Introduza o tamanho da piscina">
</div>
<div class="input-box">
<span class="details">Modalidade</span>
<input type="text" name="modality" placeholder="Introduza a modalidade">
</div>
<div class="input-box">
<span class="details">Estilo(s) de Natação</span>
<input type="text" name="swimStyle" placeholder="Introduza o estilo(s) de natação">
</div>
<div class="input-box">
<span class="details">Género</span>
<select name="gender">
<option value ="gender">Selecionar genéro</option>
<option value ="masculino">Masculino</option>
<option value ="feminino">Feminino</option>
</select>
<div class="input-box">
<span class="details">Escalão Etário</span>
<select name="gender-title">
<option value ="gender-title">Select gender group</option>
<option value ="Escola_de_natacao">ESCOLA DE NATACAO</option>
<option value ="grupos_de_natacao_desportiva">GRUPOS DE FORMACAO DESPORTIVA</option>
<option value ="cadeteA">CADETES A</option>
<option value ="cadeteB">CADETES B</option>
<option value ="infatilB">INFANTIS B</option>
<option value ="infatilA">INFANTIS A</option>
<option value ="juvenilB">JUVENIS B</option>
<option value ="juvenilA">JUVENIS A</option>
<option value ="junior">JUNIORES</option>
<option value ="senior">SENIORES</option>
</select>
</div>
<div class="title">Metadados Envio de dados</div>
<div class="input-box">
<span class="details">Utilizador Id</span>
<input type="text" name="userId" placeholder="Introduza o seu Id">
</div>
<div class="input-box">
<span class="details">Token</span>
<input type="text" name="token" placeholder="Introduza o token">
</div>
<p>Selecionar o ficheiro localmente:</p>
<input name="myFile" type="file" accept=".txt,.xlsx, .xls, .csv" >
<div class="button">
<input type="submit" id="btn-post" value="Enviar dados" onclick="do_ajax();">
<div class="input-box"></dix>
</div>
</div>
</form>
</div>
</body>
</html>
Javascript
function do_ajax() {
var input = document.querySelector('input').files;
if(!input.length){
alert("No file selected");
return;
}
var file = input[0];
var reader = new FileReader();
reader.onload = (function() {
return function(e) {
var fileData = e.target.result.trim().split('\n').map(row => row.split(','));
var HEADERS = ["time", "yaw", "pitch", "roll", "heading", "ax", "ay", "az", "gx", "gy", "gz", "mx", "my", "mz"];
const RESULT = {};
// Assign every heading to the result.
for (const HEADING of HEADERS) RESULT[HEADING] = [];
fileData.map(row =>
// Each row → each column, number of columns === number of headers
row.map((column, i) =>
RESULT[HEADERS[i]]
.push(Number(column))
));
console.log(RESULT);
};
})(file);
reader.readAsText(file);;
let fullName = document.getElementById('fullName').value;
let birthdate = document.getElementById('birthdate').value;
let height = document.getElementById('height').value;
let weight = document.getElementById('weight').value;
let poolsize = document.getElementById('poolsize').value;
let modality = document.getElementById('modality').value;
let swimStyle = document.getElementById('swimStyle').value;
var tel = document.getElementById('gender').value;
var sel = document.getElementById('gender-title').value;
console.log(sel.value);
const formdata = new FormData();
formdata.append("fullName", fullName)
formdata.append("birthdate",birthdate)
formdata.append("weight",weight)
formdata.append("height",height)
formdata.append("poolsize",poolsize)
formdata.append("modality",modality)
formdata.append("swimStyle",swimStyle)
formdata.append("gender",tel)
formdata.append("gender-title",sel)
var xhr = new XMLHttpRequest();
xhr.open('POST', '/index', true);
xhr.send(formdata);
xhr.send(JSON.stringify(RESULT));
};
FLASK
from flask import Flask, request, render_template
import pymongo
import json
app = Flask(__name__)
app.debug = True
@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
def index():
if request.method == "POST":
name = request.form["fullName"]
birthdate =request.form["birthdate"]
poolsize =request.form["poolsize"]
height =request.form["height"]
weight =request.form["weight"]
modality =request.form["modality"]
swimStyle =request.form["swimStyle"]
gender = request.form["gender"]
gender_title = request.form["gender-title"]
output = request.get_json()
print(output)
print (name,birthdate,poolsize,height,weight,modality,swimStyle)
alldata = { "sessionData": output,
"metadata":{ "birthdate": birthdate, "Name": name,
"Weight": height,"Pool_size":poolsize,
"Weight":weight,"Gender":gender,"Gender_title":gender_title,
"modality":modality, "swimStyle": swimStyle}}
return alldata,200
else:
return render_template('index.html')
if __name__ == "__main__":
app.run()
一次数据传输只能符合一种格式。此格式是表单的编码或对应于 JSON 格式。
您仍然可以在一个请求中发送数据。 您可以将 JSON-formatted 数据作为字段添加到表单中,或者将表单数据转换为 JSON 结构。
对于第一个变体,需要在服务器端手动读取 JSON 数据。您可以为此使用 python json 库。对于后者,框架会完成这项工作。
第三种选择是在表单中传输文件并在服务器端读取它。
无论您选择哪个选项,都不要忘记验证输入。
在下面的示例中,所有表单数据都被转换为JSON并发送到服务器。为了清楚起见,我稍微缩短了代码。
表单数据添加JSON格式数据的版本应该是self-explanatory.
我认为最好的解决方案是读取文件服务器端。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Read CSV to JSON</title>
</head>
<body>
<form name="my-form" method="post" enctype="" enctype="multipart/form-data">
<input type="text" name="name" />
<!-- ... -->
<input type="file" name="csv" allow="text/csv" />
<input type="submit" />
</form>
<script type="text/javascript">
((uri) => {
function readCSV(file, delim=',') {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onerror = reject;
reader.onload = (evt) => {
resolve(evt.target.result.split(/\r\n|\n/).map(line => line.split(delim)));
};
reader.readAsText(file);
});
}
function serialize(formData) {
const data = {};
for (const [k, v] of formData) data[k] = v;
return data;
}
// Register a listener for submit events and suppress the default behavior of the form.
const form = document.querySelector('form[name="my-form"]');
form.addEventListener('submit', async evt => {
evt.preventDefault();
if(!evt.target.csv.files.length) {
alert('No file selected.');
return;
}
const file = evt.target.csv.files[0];
const formData = new FormData(evt.target);
formData.delete('csv');
// Conversion of the form data into an object.
const data = serialize(formData);
// Reading and converting the file into a list of objects.
// Adding the list to the previous object.
data['csv'] = await readCSV(file, ',')
.then(csv => {
const head = ['time', 'yaw', 'pitch', 'roll', 'heading', 'ax',
'ay', 'az', 'gx', 'gy', 'gz', 'mx', 'my', 'mz'];
return csv.map(row => {
let r = {};
row.forEach((col, i) => r[head[i]] = Number(col));
return r;
});
});
// Sending the JSON data to the server.
fetch(uri, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(resp => resp.json())
.then(data => console.log(data));
});
})({{ url_for('.data') | tojson }});
</script>
</body>
</html>
from flask import Flask
from flask import (
jsonify,
render_template,
request,
)
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/data', methods=['POST'])
def data():
data = request.json
print(data)
return jsonify(success=True)