如何将 python 元组列表转换为 JavaScript 中的数组?

How to convert a python list of tuples to an array in JavaScript?

我正在尝试使用 Flask 创建一个网站,我将 HTML canvas 数据传递到数据库,然后在另一条路径中使用该数据。当我从数据库中检索数据时,它是一个列表的形式,这是一个只有一个元素的列表示例:

[(1, 'circle', '{"pencil":[{"startx":346,"starty":105,"endx":346,"endy":105,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":344,"endy":104,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":341,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":338,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":336,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":333,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":330,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":338,"endy":107,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":338,"endy":107,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":336,"endy":107,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":336,"endy":109,"thick":2,"color":"#000000"}],"line":[],"rectangle":[],"circle":[],"eraser":[]}', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAu4AAAHCCAYAAACwm0waAAAAAXNSR0IArs4c6QAAIABJREFUeF7t3W2SI9lVBuDr/vD8gOgmAsLegNkGrB22Ke4KQjEiAAAECBAgQIEBAcbcHCBAgQIAAAQIECCQQ+D/vr4ThKs0KewAAAABJRU5ErkJggg==', '10', '10', '100', '100')]

根据之前在此类问题中给出的几个答案,我尝试了以下方法,首先我使用了 json.dumps():

在烧瓶中:

files = json.dumps(files)
return render_template("edit.html", files=files)

edit.html中,我将它简单地传递给一个函数:

<button id="show" onclick="loadImages(`{{ files }}`)">View</button>

最后在edit.js,我试着用数组读取如下:

function loadImages(sources) {
    var canvas = document.getElementById("paint");    
    var ctx = canvas.getContext("2d");

    console.log(sources);
    
    sources = JSON.parse(sources);
    console.log(typeof(sources)); 
    for(var i = 0; i < sources.length; i++) {
        ctx.drawImage(sources[i][3], sources[i][4], sources[i][5], sources[i][6], sources[i][7]);
    
    }
  }

但是这个returns一个错误:

Uncaught SyntaxError: Unexpected token p in JSON at position 18
    at JSON.parse (<anonymous>)
    at loadImages (edit.js:16)
    at HTMLButtonElement.onclick (edit:39)

loadImages函数中console.log(sources)的输出为:

[[1, "circle", "{"pencil":[{"startx":346,"starty":105,"endx":346,"endy":105,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":344,"endy":104,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":341,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":338,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":336,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":333,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":330,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":326,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":326,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":322,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":319,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":317,"endy":103,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":315,"endy":104,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":314,"endy":104,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":312,"endy":104,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":311,"endy":105,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":310,"endy":106,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":308,"endy":106,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":307,"endy":107,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":306,"endy":107,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":304,"endy":109,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":302,"endy":110,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":301,"endy":111,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":336,"endy":107,"thick":2,"color":"#000000"},{"startx":346,"starty":105,"endx":336,"endy":109,"thick":2,"color":"#000000"}],"line":[],"rectangle":[],"circle":[],"eraser":[]}", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAu4AAAHCCAYAAACwm0waAAAAAXNSR0IArs4c6QAAIABJREFUeF7t3W2SI9lVBuDr/vD8gOgmAsLegNkGrB22ARuAgAimDT/G022ItCuH7LRUkkpS3vPxTITDMK5Snvu8N1VvZ6eyfjX8Q4AAAQIECBAgQIBAeIFfhZ/QgAQIECBAgAABAgQIDMXdJiBAgAABAgQIECCQQEBxTxCSEQkQIECAAAECBAgo7vYAAQIECBAgQIAAgQQCinuCkIxIgAABAgQIECBAQHG3BwgQIECAAAECBAgkEFDcE4RkRAIECBAgQIAAAQKKuz1AgAABAgQIECBAIIGA4p4gJCMSIECAAAECBAgQUNztAQIECBAgQIAAAQIJBBT3BCEZkQABAgQIECBAgIDibg8QIECAAAECBAgQSCCguCcIyYgECBAgQIAAAQIEFHd7gAABAgQIECBAgEACAcU9QUhGJECAAAECBAgQIKC42wMECBAgQIAAAQIEEggo7glCMiIBAgQIECBAgAABxd0eIECAAAECBAgQIJBAQHFPEJIRCRAgQIAAAQIECCju9gABAgQIECBAgACBBAKKe4KQjEiAAAECBAgQIEBAcbcHCBAgQIAAAQIECCQQUNwThGREAgQIECBAgAABAoq7PUCAAAECBAgQIEAggYDiniAkIxIgQIAAAQIECBBQ3O0BAgQIECBAgAABAgkEFPcEIRmRAAECBAgQIECAgOJuDxAgQIAAAQIECBBIIKC4JwjJiAQIECBAgAABAgQUd3uAAAECBAgQIECAQAIBxT1BSEYkQIAAAQIECBAgoLjbAwQIECBAgAABAgQSCCjuCUIyIgECBAgQIECAAAHF3R4gQIAAAQIECBAgkEBAcU8QkhEJECBAgAABAgQIKO72AAECBAgQIECAAIEEAop7gpCMSIAAAQIECBAgQEBxtwcIECBAgAABAgQIJBBQ3BOEZEQCBAgQIECAAAECirs9QIAAAQIECBAgQCCBgOKeICQjEiBAgAABAgQIEFDc7QECBAgQIECAAAECCQQU9wQhGZEAAQIECBAgQICA4m4PECBAgAABAgQIEEggoLgnCMmIBAgQIECAAAECBBR3e4AAAQIECBAgQIBAAgHFPUFIRiRAgAABAgQIECCguNsDBAgQIECAAAECBBIIKO4JQjIiAQIECBAgQIAAAcXdHiBAgAABAgQIECCQQEBxTxCSEQkQIECAAAECBAgo7vYAAQIECBAgQIAAgQQCinuCkIxIgAABAgQIECBAQHG3BwgQIECAAAECBAgkEFDcE4RkRAIECBAgQIAAAQKKuz1AgAABAgQIECBAIIGA4p4gJCMSIECAAAECBAgQUNztAQIECBAgQIAAAQIJBBT3BCEZkQABAgQIECBAgIDibg8QIECAAAECBAgQSCCguCcIyYgECBAgQIAAAQIEFHd7gAABAgQIECBAgEACAcU9QUhGJECAAAECBAgQIKC42wMECBAgQIAAAQIEEggo7glCMiIBAgQIECBAgAABxd0eIECAAAECBAgQIJBAQHFPEJIRCRAgQIAAAQIECCju9gABAgQIECBAgACBBAKKe4KQjEiAAAECBAgQIEBAcbcHCBAgQIAAAQIECCQQUNwThGREAgQIECBAgAABAoq7PUCAAAECBAgQIEAggYDiniAkIxIgQIAAAQIECBBQ3O0BAgQIECBAgAABAgkEFPcEIRmRAAECBAgQIECAgOJuDxAgQIAAAQIECBBIIKC4JwjJiAQIECBAgAABAgQUd3uAAAECBAgQIECAQAIBxT1BSEYkQIAAAQIECBAgoLjbAwQIECBAgAABAgQSCCjuCUIyIgECBAgQIECAAAHF3R4gQIAAAQIECBAgkEBAcU8QkhEJECBAgAABAgQIKO72AAECBAgQIECAAIEEAop7gpCMSIAAAQIECBAgQEBxtwcIECBAgAABAgQIJBBQ3BOEZEQCBAgQIECAAAECirs9QIAAAQIECBAgQCCBgOKeICQjEiBAgAABAgQIEFDc7QECBAgQIECAAAECCQQU9wQhGZEAAQIECBAgQICA4m4PECBAgAABAgQIEEggoLgnCMmIBAgQIECAAAECBBR3e4AAAQIECBAgQIBAAgHFPUFIRiRAgAABAgQIECCguNsDBAgQIECAAAECBBIIKO4JQjIiAQIECBAgQIAAAcXdHiBAgAABAgQIECCQQEBxTxCSEQkQIECAAAECBAgo7vYAAQIECBAgQIAAgQQCinuCkIxIgAABAgQIECBAQHG3BwgQ6CLwxzHGke95X8cYH7vgWicBAgQIPF/gyB9iz1+NIxAgQODPAj+OMT4FwfjfMca7ILMYgwABAgQSCyjuicMzOgECJwVeK+1HlOifxxgfdpMtV/vfy4sAAQIECNwggg==", "10", "10", "100", "100"]]

我尝试了多种方法来完成这项工作,但这是我最接近我想要的方法,我该如何继续纠正这个问题?

我在这段代码中发现了一些问题 - 所有问题都与模板有关:

  1. flask 中的模板会转义数据(以使其更安全),因此使用 {{ file }} 它会创建 HTML 和

    [[1, &#34;circle&#34;, &#34;{\&#34;pencil\&#34;:[
    

    如果你使用Show Page Source( Ctrl+U),你可以在浏览器中看到它。

    创建正确的 HTML

    需要 {{ file|safe }}
    [[1, "circle", "{\"pencil\":[ 
    
  2. loadImages( ``...`` )

    中不需要刻度
  3. 因为 files 把字符串放在 " " 所以 loadImage 必须在 ' '

    onclick='loadImages({{ files|safe }})'
    
  4. 浏览器将来自 files 的文本视为普通代码,因此它在加载时解析数据并且不需要 JSON.parse()

  5. 要绘制图像,您必须创建 Image 并将数据分配给 .src

         var img = new Image();
         img.src = sources[i][3];
    
         ctx.drawImage(img, ...)
    

最少的工作代码

编辑:

您不必使用 json.dumps(data){{ data|tojson }}

最终您可以使用 {{ data|safe }},但需要将一些 " " 更改为 ' '

from flask import Flask, request, render_template_string
import json

app = Flask(__name__)

data = [(1, 'circle',
         '{"pencil":[\
             {"startx":346,"starty":105,"endx":346,"endy":105,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":344,"endy":104,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":341,"endy":103,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":338,"endy":103,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":336,"endy":103,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":333,"endy":103,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":330,"endy":103,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":338,"endy":107,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":338,"endy":107,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":336,"endy":107,"thick":2,"color":"#000000"},\
             {"startx":346,"starty":105,"endx":336,"endy":109,"thick":2,"color":"#000000"}],\
          "line":[],"rectangle":[],"circle":[],"eraser":[]\
         }',
         'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAAAAACoWZBhAAAAMklEQVR4nEXNwQkAMBACwfFI/y2bxwXia8FFUwF1pCCNJTIIwaD04ctsKRyaldI/9i8u1iwOE6FA880AAAAASUVORK5CYII=',
         '10', '10', '10', '10'
)]

@app.route('/', methods=['GET', 'POST'])
def index():
    text = json.dumps(data)
    return render_template_string('''
<script>
function loadImages(sources) {
    console.log(sources);

    var canvas = document.getElementById("paint");    
    var ctx = canvas.getContext("2d");
    
    for(var i = 0; i < sources.length; i++) {
        var data = sources[i]
        console.log(data[3]);
        var img = new Image();
        img.src = data[3];
        ctx.drawImage(img, data[4], data[5]); //, data[6], data[7]);
    }
}
</script>

<body>
<h1>files</h1>
<pre>{{ files }}</pre>
<h1>files|safe</h1>
<pre>{{ files|safe }}</pre>
<h1>files|tojson</h1>
<pre>{{ files|tojson }}</pre>
<hr>

<canvas id="paint" width="100" height="100"></canvas><br/>

<button id="show" onclick='loadImages({{ files|safe <button id="show" onclick='loadImages({{ files|safe }})'>View files|safe</button>

<button id="show" onclick='loadImages({{ data|tojson }})'>View data|tojson</button>

<button id="show" onclick="loadImages({{ data|safe }})">View data|safe</button>

</body>
''', files=text, data=data)
if __name__ == '__main__':
    #app.debug = True 
    app.run()

对于你的 data:image 我收到错误 image broken 所以我使用我的小图标 10x10

但我不知道为什么,有时我必须点击按钮两次才能看到图像。