如何将数据列表从烧瓶传递到 JS?
How to pass lists of data from flask to JS?
我的 python Flask 服务器中有一组列表,即 c_data
、data
、targetx
、targety
、sizex
和 sizey
。它们看起来像下面这样:
c_data: ['{"pencil":[[{"startx":183,"starty":165,"endx":183,"endy":167,"thick":2,"color":"#000000"},{"startx":183,"starty":167,"endx":187,"endy":169,"thick":2,"color":"#000000"},{"startx":187,"starty":169,"endx":188,"endy":171,"thick":2,"color":"#000000"},{"startx":188,"starty":171,"endx":190,"endy":172,"thick":2,"color":"#000000"},{"startx":190,"starty":172,"endx":190,"endy":174,"thick":2,"color":"#000000"},{"startx":190,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"},{"startx":191,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"}]],"line":[],"rectangle":[],"circle":[],"eraser":[],"last_action":[0]}']
data: ['data:image/png;base64,iVBORw0KG.......(basically a very long string of base64 encoding)]
targetx: [369]
targety: [252]
sizex: [100]
sizey: [100]
(c_data
在js文件中声明为canvas_data = {"pencil": [], "line": [], "rectangle": [], "circle": [], "eraser": [], "last_action": [] };
,这可能有助于你更好地理解c_data
的结构)
如何传递这些列表以便我可以在 JS 中再次阅读它们?
这是我的尝试,在 app.py
文件中,我首先执行以下操作将数据发送到脚本:
c_data = json.dumps(c_data)
data = json.dumps(data)
targetx = json.dumps(targetx)
targety = json.dumps(targety)
sizex = json.dumps(sizex)
sizey = json.dumps(sizey)
return jsonify({'result': 'success', 'c_data': c_data, 'data': data, 'targetx': targetx, 'targety': targety, 'sizex': sizex, 'sizey': sizey})
我通过渲染 HTML 将它传递给 Jinja,我在 JavaScript 中也有一个名为 pencil()
的函数,我使用它尝试了这样的事情:
<body onload="pencil(`{{ c_data }}`, `{{ data }}`, `{{ targetx }}`, `{{ targety }}`, `{{ sizex }}`, `{{ sizey }}`)">
并且在我的 script.js 中,我通过以下方式使用传递的数据来读取它们:
async function loadImages(c_data, data, targetX, targetY, targetWidth, targetHeight) {
c_data = c_data.replace(/'/g, '"');
data = data.replace(/'/g, '"');
targetX = targetX.replace(/'/g, '"');
targetY = targetY.replace(/'/g, '"');
targetWidth = targetWidth.replace(/'/g, '"');
targetHeight = targetHeight.replace(/'/g, '"');
c_data = JSON.parse(c_data);
data = JSON.parse(data);
targetX = JSON.parse(targetX);
targetY = JSON.parse(targetY);
targetWidth = JSON.parse(targetWidth);
targetHeight = JSON.parse(targetHeight);
for (var i = 0; i < data.length; i++) {
var tx = parseInt(targetX[i]);
var ty = parseInt(targetY[i]);
var tw = parseInt(targetWidth[i]);
var th = parseInt(targetHeight[i]);
var img = {
src: await loadImage(data[i], i),
c_data: c_data[i],
ul: {
x: tx,
y: ty
},
ur: {
x: tx + tw,
y: ty
},
ll: {
x: tx,
y: ty + th
},
lr: {
x: tx + tw,
y: ty + th
}
};
images.push(img)
}
draw_canvas();
}
使用这种方法,所有数据都工作正常 除了 c_data
,它没有转换为我期望的 canvas_data
对象类型并且它的字符串中有一些反斜杠。当我尝试使用 c_data = c_data.replace(/\/g, '');
行删除反斜杠时,出现错误:
Uncaught (in promise) SyntaxError: Unexpected token p in JSON at position 4
如何将上述数据类型正确解析为JS并读取?
从您的解释中推断出您的代码有点困难。
如果在服务器端省略json.dumps
,就不用在浏览器中再次解析数据了。这消除了当时不必要的 JSON.parse
.
调用
可以通过多种方式将数据从 Flask 传递到 JavaScript。
1) 使用 tojson 过滤器:
一种可能是像往常一样将数据传输到模板,然后使用 Jinja 过滤器 tojson
.
将其转换为 JSON
from flask import (
Flask,
render_template
)
app = Flask(__name__)
@app.route('/')
def index():
c_data = {
"pencil":[
[
{"startx":183,"starty":165,"endx":183,"endy":167,"thick":2,"color":"#000000"},
{"startx":183,"starty":167,"endx":187,"endy":169,"thick":2,"color":"#000000"},
{"startx":187,"starty":169,"endx":188,"endy":171,"thick":2,"color":"#000000"},
{"startx":188,"starty":171,"endx":190,"endy":172,"thick":2,"color":"#000000"},
{"startx":190,"starty":172,"endx":190,"endy":174,"thick":2,"color":"#000000"},
{"startx":190,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"},
{"startx":191,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"}
]
],
"line":[],
"rectangle":[],
"circle":[],
"eraser":[],
"last_action":[0]
}
data = 'data:image/png;base64,iVBORw0KG.......(basically a very long string of base64 encoding)'
targetx = [369]
targety = [252]
sizex = [100]
sizey = [100]
return render_template('index.html', **locals())
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
((cData, data, targetX, targetY, sizeX, sizeY) => {
function pencil(cData, data, targetX, targetY, sizeX, sizeY) {
console.log(cData, data, targetX, targetY, sizeX, sizeY);
}
window.addEventListener('DOMContentLoaded', () => {
pencil(cData, data, targetX, targetY, sizeX, sizeY);
});
})(
{{ c_data | tojson }},
{{ data | tojson }},
{{ targetx | tojson }},
{{ targety | tojson }},
{{ sizex | tojson }},
{{ sizey | tojson }}
);
</script>
</body>
</html>
2) 获取使用jsonify转换的数据:
另一种可能性是通过AJAX从另一个端点获取数据。服务器端使用jsonify
.
将数据转换成JSON格式
from flask import (
Flask,
render_template,
jsonify
)
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/data')
def data():
c_data = {
"pencil":[
[
{"startx":183,"starty":165,"endx":183,"endy":167,"thick":2,"color":"#000000"},
{"startx":183,"starty":167,"endx":187,"endy":169,"thick":2,"color":"#000000"},
{"startx":187,"starty":169,"endx":188,"endy":171,"thick":2,"color":"#000000"},
{"startx":188,"starty":171,"endx":190,"endy":172,"thick":2,"color":"#000000"},
{"startx":190,"starty":172,"endx":190,"endy":174,"thick":2,"color":"#000000"},
{"startx":190,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"},
{"startx":191,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"}
]
],
"line":[],
"rectangle":[],
"circle":[],
"eraser":[],
"last_action":[0]
}
data = 'data:image/png;base64,iVBORw0KG.......(basically a very long string of base64 encoding)'
targetx = [369]
targety = [252]
sizex = [100]
sizey = [100]
return jsonify(
c_data=c_data,
data=data,
targetx=targetx, targety=targety,
sizex=sizex, sizey=sizey
)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
(async (uri) => {
function pencil(cData, data, targetX, targetY, sizeX, sizeY) {
console.log(cData, data, targetX, targetY, sizeX, sizeY);
}
const dat = await fetch(uri).then(resp => resp.json());
const { c_data, data, targetx, targety, sizex, sizey } = dat;
pencil(c_data, data, targetx, targety, sizex, sizey);
})({{ url_for('data') | tojson }});
</script>
</body>
</html>
我的 python Flask 服务器中有一组列表,即 c_data
、data
、targetx
、targety
、sizex
和 sizey
。它们看起来像下面这样:
c_data: ['{"pencil":[[{"startx":183,"starty":165,"endx":183,"endy":167,"thick":2,"color":"#000000"},{"startx":183,"starty":167,"endx":187,"endy":169,"thick":2,"color":"#000000"},{"startx":187,"starty":169,"endx":188,"endy":171,"thick":2,"color":"#000000"},{"startx":188,"starty":171,"endx":190,"endy":172,"thick":2,"color":"#000000"},{"startx":190,"starty":172,"endx":190,"endy":174,"thick":2,"color":"#000000"},{"startx":190,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"},{"startx":191,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"}]],"line":[],"rectangle":[],"circle":[],"eraser":[],"last_action":[0]}']
data: ['data:image/png;base64,iVBORw0KG.......(basically a very long string of base64 encoding)]
targetx: [369]
targety: [252]
sizex: [100]
sizey: [100]
(c_data
在js文件中声明为canvas_data = {"pencil": [], "line": [], "rectangle": [], "circle": [], "eraser": [], "last_action": [] };
,这可能有助于你更好地理解c_data
的结构)
如何传递这些列表以便我可以在 JS 中再次阅读它们?
这是我的尝试,在 app.py
文件中,我首先执行以下操作将数据发送到脚本:
c_data = json.dumps(c_data)
data = json.dumps(data)
targetx = json.dumps(targetx)
targety = json.dumps(targety)
sizex = json.dumps(sizex)
sizey = json.dumps(sizey)
return jsonify({'result': 'success', 'c_data': c_data, 'data': data, 'targetx': targetx, 'targety': targety, 'sizex': sizex, 'sizey': sizey})
我通过渲染 HTML 将它传递给 Jinja,我在 JavaScript 中也有一个名为 pencil()
的函数,我使用它尝试了这样的事情:
<body onload="pencil(`{{ c_data }}`, `{{ data }}`, `{{ targetx }}`, `{{ targety }}`, `{{ sizex }}`, `{{ sizey }}`)">
并且在我的 script.js 中,我通过以下方式使用传递的数据来读取它们:
async function loadImages(c_data, data, targetX, targetY, targetWidth, targetHeight) {
c_data = c_data.replace(/'/g, '"');
data = data.replace(/'/g, '"');
targetX = targetX.replace(/'/g, '"');
targetY = targetY.replace(/'/g, '"');
targetWidth = targetWidth.replace(/'/g, '"');
targetHeight = targetHeight.replace(/'/g, '"');
c_data = JSON.parse(c_data);
data = JSON.parse(data);
targetX = JSON.parse(targetX);
targetY = JSON.parse(targetY);
targetWidth = JSON.parse(targetWidth);
targetHeight = JSON.parse(targetHeight);
for (var i = 0; i < data.length; i++) {
var tx = parseInt(targetX[i]);
var ty = parseInt(targetY[i]);
var tw = parseInt(targetWidth[i]);
var th = parseInt(targetHeight[i]);
var img = {
src: await loadImage(data[i], i),
c_data: c_data[i],
ul: {
x: tx,
y: ty
},
ur: {
x: tx + tw,
y: ty
},
ll: {
x: tx,
y: ty + th
},
lr: {
x: tx + tw,
y: ty + th
}
};
images.push(img)
}
draw_canvas();
}
使用这种方法,所有数据都工作正常 除了 c_data
,它没有转换为我期望的 canvas_data
对象类型并且它的字符串中有一些反斜杠。当我尝试使用 c_data = c_data.replace(/\/g, '');
行删除反斜杠时,出现错误:
Uncaught (in promise) SyntaxError: Unexpected token p in JSON at position 4
如何将上述数据类型正确解析为JS并读取?
从您的解释中推断出您的代码有点困难。
如果在服务器端省略json.dumps
,就不用在浏览器中再次解析数据了。这消除了当时不必要的 JSON.parse
.
可以通过多种方式将数据从 Flask 传递到 JavaScript。
1) 使用 tojson 过滤器:
一种可能是像往常一样将数据传输到模板,然后使用 Jinja 过滤器 tojson
.
from flask import (
Flask,
render_template
)
app = Flask(__name__)
@app.route('/')
def index():
c_data = {
"pencil":[
[
{"startx":183,"starty":165,"endx":183,"endy":167,"thick":2,"color":"#000000"},
{"startx":183,"starty":167,"endx":187,"endy":169,"thick":2,"color":"#000000"},
{"startx":187,"starty":169,"endx":188,"endy":171,"thick":2,"color":"#000000"},
{"startx":188,"starty":171,"endx":190,"endy":172,"thick":2,"color":"#000000"},
{"startx":190,"starty":172,"endx":190,"endy":174,"thick":2,"color":"#000000"},
{"startx":190,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"},
{"startx":191,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"}
]
],
"line":[],
"rectangle":[],
"circle":[],
"eraser":[],
"last_action":[0]
}
data = 'data:image/png;base64,iVBORw0KG.......(basically a very long string of base64 encoding)'
targetx = [369]
targety = [252]
sizex = [100]
sizey = [100]
return render_template('index.html', **locals())
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
((cData, data, targetX, targetY, sizeX, sizeY) => {
function pencil(cData, data, targetX, targetY, sizeX, sizeY) {
console.log(cData, data, targetX, targetY, sizeX, sizeY);
}
window.addEventListener('DOMContentLoaded', () => {
pencil(cData, data, targetX, targetY, sizeX, sizeY);
});
})(
{{ c_data | tojson }},
{{ data | tojson }},
{{ targetx | tojson }},
{{ targety | tojson }},
{{ sizex | tojson }},
{{ sizey | tojson }}
);
</script>
</body>
</html>
2) 获取使用jsonify转换的数据:
另一种可能性是通过AJAX从另一个端点获取数据。服务器端使用jsonify
.
from flask import (
Flask,
render_template,
jsonify
)
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/data')
def data():
c_data = {
"pencil":[
[
{"startx":183,"starty":165,"endx":183,"endy":167,"thick":2,"color":"#000000"},
{"startx":183,"starty":167,"endx":187,"endy":169,"thick":2,"color":"#000000"},
{"startx":187,"starty":169,"endx":188,"endy":171,"thick":2,"color":"#000000"},
{"startx":188,"starty":171,"endx":190,"endy":172,"thick":2,"color":"#000000"},
{"startx":190,"starty":172,"endx":190,"endy":174,"thick":2,"color":"#000000"},
{"startx":190,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"},
{"startx":191,"starty":174,"endx":191,"endy":174,"thick":2,"color":"#000000"}
]
],
"line":[],
"rectangle":[],
"circle":[],
"eraser":[],
"last_action":[0]
}
data = 'data:image/png;base64,iVBORw0KG.......(basically a very long string of base64 encoding)'
targetx = [369]
targety = [252]
sizex = [100]
sizey = [100]
return jsonify(
c_data=c_data,
data=data,
targetx=targetx, targety=targety,
sizex=sizex, sizey=sizey
)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
(async (uri) => {
function pencil(cData, data, targetX, targetY, sizeX, sizeY) {
console.log(cData, data, targetX, targetY, sizeX, sizeY);
}
const dat = await fetch(uri).then(resp => resp.json());
const { c_data, data, targetx, targety, sizex, sizey } = dat;
pencil(c_data, data, targetx, targety, sizex, sizey);
})({{ url_for('data') | tojson }});
</script>
</body>
</html>