I have a Flask app with some vanilla Javascript (I don't know JQuery). It does the following: (1) The user enters some data in an HTML table. (2) The data is then parsed to JSON. (3) I want to post the JSON file to the server. (4) From the server, the JSON object is posted to a different REST API for further use.
Steps 1, 2 and 4 work (I can console.log
the JSON object), but I'm at a loss how to post a JSON object from client to server. The option I keep seeing is to move the table between tags and then post the table via request.form
. I'm happy to do that but it seems clunky compared to parsing JSON on the client side and posting a clean object to the server that can be used immediately by the third-party REST API. What am I missing here?
<!DOCTYPE html>
<html>
<body>
<body>
<button id="click">Click</button>
<table id="myTable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>001</td>
<td>Trousers</td>
<td>9.99</td>
</tr>
<tr>
<td>002</td>
<td>Shirt</td>
<td>19.99</td>
</tr>
<tr>
<td>003</td>
<td>Shoes</td>
<td>49.99</td>
</tr>
</tbody>
</table>
</body>
<script>
const btn = document.getElementById("click");
btn.addEventListener("click", function () {
tableToJson(table);
})
let table = document.getElementById("myTable");
function tableToJson(table) {
var data = [];
// first row needs to be headers
var headers = [];
for (var i=0; i<table.rows[0].cells.length; i ) {
headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
}
// go through cells
for (var i=1; i<table.rows.length; i ) {
var tableRow = table.rows[i];
var rowData = {};
for (var j=0; j<tableRow.cells.length; j ) {
rowData[ headers[j] ] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
console.log(data);
return data;
}
</script>
</html>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
app = Flask(__name__) # Create an Instance
@app.route('/', methods=['GET', 'POST']) # Route the Function and allow Requests
def main(): # Run the function
if request.method == 'POST': # Identify Request Method
value = request.form['input'] # Gather the Post Request
return value
if request.method == 'GET': # Identify Request Method
return render_template('index.html')
app.run(host='0.0.0.0', port=5000, debug=True) # Run the Application (in debug mode)```
CodePudding user response:
Use the Fetch API to send the data.
In the following example, the data is converted into a JSON-compliant character string and sent to the server via POST.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button id="click">Click</button>
<table id="my-table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>001</td>
<td>Trousers</td>
<td>9.99</td>
</tr>
<tr>
<td>002</td>
<td>Shirt</td>
<td>19.99</td>
</tr>
<tr>
<td>003</td>
<td>Shoes</td>
<td>49.99</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
(() => {
const tableToJSON = (tableElem) => {
const tableRows = Array.from(tableElem.rows);
const tableHead = Array.from(tableRows[0].cells).map(cell => {
return cell.innerHTML.toLowerCase().replace(/ /g,'_')
});
return tableRows.slice(1).map(row => {
const rowData = {}
Array.from(row.cells).forEach((cell, i) => {
return rowData[tableHead[i]] = cell.innerHTML;
});
return rowData;
});
};
const btnElem = document.getElementById('click');
btnElem.addEventListener('click', (evt) => {
const tableElem = document.getElementById('my-table');
const tableData = tableToJSON(tableElem);
// Post JSON data to the server.
const url = '/data';
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(tableData)
}).then(resp => resp.json())
.then(data => console.log(data));
});
})();
</script>
</body>
</html>
Then you can request and process the data on the server using request.get_json()
. The response from the server is a simple JSON object that was converted with jsonify.
from flask import Flask
from flask import render_template, request, jsonify
app = Flask(__name__)
app.secret_key = 'your secret here'
@app.route('/', methods=['GET'])
def index():
return render_template('index.html')
@app.route('/data', methods=['POST'])
def data():
data = request.get_json()
print(data)
return jsonify(success=True)