简体   繁体   English

如何将数据列表从 flask 传递给 JS?

[英]How to pass lists of data from flask to JS?

I have a set of lists in my python Flask server, namely c_data , data , targetx , targety , sizex and sizey .我的 python Flask 服务器中有一组列表,即c_datadatatargetxtargetysizexsizey They look something like the following:它们看起来像下面这样:

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]

(The c_data is declared in the js file as canvas_data = {"pencil": [], "line": [], "rectangle": [], "circle": [], "eraser": [], "last_action": [] }; , this may help you understand the structure of c_data better) c_data在js文件中声明为canvas_data = {"pencil": [], "line": [], "rectangle": [], "circle": [], "eraser": [], "last_action": [] }; ,这可能有助于您更好地理解c_data的结构)

How do I pass these lists so that I can then read them again in JS?我如何传递这些列表以便我可以在 JS 中再次阅读它们?

Here's what I tried, in the app.py file, I first did the following to send the data to the scripts:这是我尝试的,在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})

and I pass it to Jinja by rendering HTML, and I also have a function in JavaScript called pencil() , using which I tried something like this:我通过渲染 HTML 将它传递给 Jinja,我在 JavaScript 中也有一个 function 称为pencil() ,我使用它尝试了这样的事情:

<body onload="pencil(`{{ c_data }}`, `{{ data }}`, `{{ targetx }}`, `{{ targety }}`, `{{ sizex }}`, `{{ sizey }}`)">

and in my script.js , I used the passed data in the following way to read them:在我的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();
}

Using this approach, all the data works fine except c_data , which does not get converted to the canvas_data object type which I was expecting and has some backslashes in its string.使用这种方法,除了c_data之外的所有数据都工作正常,它没有转换为我期望的canvas_data object 类型,并且在其字符串中有一些反斜杠。 And when I try to remove the backslashes using the line c_data = c_data.replace(/\\/g, '');当我尝试使用c_data = c_data.replace(/\\/g, '');行删除反斜杠时I get the error:我收到错误:

Uncaught (in promise) SyntaxError: Unexpected token p in JSON at position 4

How do I correctly parse the above data types to JS and read them?如何将上述数据类型正确解析为JS并读取?

It's a little difficult to deduce your code from your explanations.从您的解释中推断出您的代码有点困难。

If you omit json.dumps on the server, you don't have to parse the data again in the browser.如果在服务器端省略了json.dumps ,就不用在浏览器中再次解析数据了。 This eliminates the then unnecessary calls of JSON.parse .这消除了当时不必要的JSON.parse调用。

Data can be passed from Flask to JavaScript in a number of ways.数据可以通过多种方式从 Flask 传递到 JavaScript。

1) Using the tojson filter: 1)使用tojson过滤器:

One possibility is to transfer the data to the template as usual and then convert it to JSON with the Jinja filter tojson .一种可能是像往常一样将数据传输到模板,然后使用 Jinja 过滤器 tojson 将其转换为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) Get data converted with jsonify: 2)获取使用jsonify转换的数据:

Another possibility is to obtain the data from another endpoint via AJAX. The data is converted into JSON format on the server side using 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM