2017-02-28 259 views
3

我遇到了将Flask/Python变量传递给Javascript的麻烦。将JSON对象从Flask传递到JavaScript

基本上,我从MySQL导入并尝试以三种不同的方式渲染返回。

  1. (43.8934276, -103.3690243), (47.052060, -91.639868), (45.1118, -95.0396)即输出时,我的字典项上有以下跑去。

new_list = [tuple(d.values()) for d in MySQL_Dict] output = ', '.join('(' + ', '.join(i) + ')' for i in new_list)

这种方法是不行的,但我加了它的细节,这是不正确的格式在所有。

  • 我直接传递蟒字典到看起来像这样
  • ({'lat': '43.8934276', 'lng': '-103.3690243'}, {'lat': '47.052060', 'lng': '-91.639868'}, {'lat': '45.1118', 'lng': '-95.0396'})

    然后在模板侧我尝试下面的JavaScript模板行

    var other_coords = {{ MySQL_Dict|tojson }}; 
    var other_coords = {{ MySQL_Dict|tojson|safe }}; 
    var still_more = JSON.parse(other_coords); 
    

    没有一起工作,一起或分开。

    1. 我也试着用json_out = json.dumps(My_Dict)这个视图发送字典,这也不起作用。

    这样做的目的都是为了从MySQL DB到Google Maps API脚本获取经纬度坐标。对我来说如此令人困惑的事情是,如果我只是将视图中的json.dump结果粘贴到Google Maps脚本中,那么它完美地工作(删除引号后),但如果我使用变量,它将不适用于我。有没有人有建议?

    +0

    呈现的HTML中所需的输出是什么? –

    +0

    Google地图上的标记。 – BrettJ

    +0

    对不起,我是指你要找什么输出格式(坐标)? –

    回答

    10

    看来,目前接受的答案(by @BrettJ)有可能le安全漏洞:如果我们传递给javascript的对象有一些内部带有单引号的字符串,这个单引号不会被json.dumps转义,从而允许将任意代码注入到javascript中。最好使用Flask的tojson()模板过滤器,请参阅the docs,因为它可以正确地转义所有这些字符(将它们替换为unicode代码)。

    这里是我的解决方案:

    view.py

    from flask import Flask, render_template 
    
    app = Flask(__name__) 
    
    @app.route('/') 
    def hello_world(): 
        user = {'firstname': "Mr.", 'lastname': "My Father's Son"} 
        return render_template("index.html", user=user) 
    
    if __name__ == '__main__': 
        app.run() 
    

    指数。HTML

    <p>Hello, <span id="username"></span></p> 
    <script> 
        var user = JSON.parse('{{ user | tojson | safe}}'); 
        document.getElementById('username').innerHTML = user.firstname + " " + 
          user.lastname; 
    </script> 
    

    生成JS的样子:

    var user = JSON.parse('{"firstname": "Mr.", "lastname": "My Father\u0027s Son"}'); 
    

    这是完全安全的。举例来说,如果我们可以使用json.dumps -Powered的解决方案,我们会得到

    var user = JSON.parse('{"firstname": "Mr.", "lastname": "My Father's Son"}'); 
    

    这是语法不正确(至少可以这样说)。

    +1

    您的回答适合我。我改变了我接受的答案,更好的安全总是等于更好的代码。 – BrettJ

    +0

    非常感谢!你为我节省了很多时间! :) – Teemo

    2

    下面简单的例子应该展示如何从你的字典得到一个Javascript对象:

    views.py

    @app.route('/', methods=['GET','POST'])           
    def index():                  
    
        points = [{"lat": 43.8934276, "lng": -103.3690243},       
           {"lat": 47.052060, "lng": -91.639868},        
           {"lat": 45.1118, "lng": -95.0396}]         
    
        return render_template("index.html", points=json.dumps(points)) 
    

    的index.html(一些代码为简洁,删除)

    function initMap() {              
    
        var map = new google.maps.Map(document.getElementById('map'), {   
         center: new google.maps.LatLng(43.8934276, -103.3690243),    
         zoom: 4                
        });                  
    
        var points = JSON.parse('{{ points|safe }}');       
        var marker;                
    
        for (var i = 0; i < points.length; i++) {        
    
         marker = new google.maps.Marker({         
          position: new google.maps.LatLng(points[i].lat, points[i].lng), 
          map: map               
         });                 
    
        }                  
        } 
    
    +0

    谢谢你的回答!好的,那为什么会这样呢?如果我按照你所说的做了所有事情,标记就不会出现在地图上。在Google Maps中,我只是设置'var locations = points;'但是,如果我复制并粘贴你定义的点var的输出,并执行'var locations = [{lat:43.8934276,lng:-103.3690243}, {lat:47.05206,lng:-91.639868},{lat:45.1118,lng:-95.0396}]'直接进入地图脚本,它完美的工作!...我很困惑。 – BrettJ

    +0

    我已经添加了一些示例Javascript来渲染地图上的标记。在本地进行测试,并为我呈现标记。希望这可以帮助! –

    +0

    你先生是上帝!非常感谢。这一次我最大的问题是实际的地图脚本本身......多么令人失望。万分感谢!! – BrettJ

    相关问题