[javascript] Flask의 데이터를 템플릿의 JavaScript로 어떻게 전달할 수 있습니까?

내 앱은 사전을 반환하는 API를 호출합니다. 이 dict의 정보를 뷰의 JavaScript로 전달하고 싶습니다. 특히 JS에서 Google Maps API를 사용하고 있으므로 long / lat 정보가 포함 된 튜플 목록을 전달하고 싶습니다. render_templateHTML에서 사용할 수 있도록 이러한 변수를 뷰에 전달 한다는 것을 알고 있지만 템플릿의 JavaScript에 어떻게 전달할 수 있습니까?

from flask import Flask
from flask import render_template

app = Flask(__name__)

import foo_api

api = foo_api.API('API KEY')

@app.route('/')
def get_data():
    events = api.call(get_event, arg0, arg1)
    geocode = event['latitude'], event['longitude']
    return render_template('get_data.html', geocode=geocode)



답변

{{ variable }}HTML 부분뿐만 아니라 템플릿의 어느 곳에서나 사용할 수 있습니다 . 따라서 이것은 작동합니다.

<html>
<head>
  <script>
    var someJavaScriptVar = '{{ geocode[1] }}';
  </script>
</head>
<body>
  <p>Hello World</p>
  <button onclick="alert('Geocode: {{ geocode[0] }} ' + someJavaScriptVar)" />
</body>
</html>

2 단계 프로세스로 생각하십시오. 첫째, Jinja (Flask가 사용하는 템플릿 엔진)는 텍스트 출력을 생성합니다. 이것은 그가 보는 JavaScript를 실행하는 사용자에게 전송됩니다. Flask 변수를 JavaScript에서 배열로 사용하려면 출력에서 ​​배열 정의를 생성해야합니다.

<html>
  <head>
    <script>
      var myGeocode = ['{{ geocode[0] }}', '{{ geocode[1] }}'];
    </script>
  </head>
  <body>
    <p>Hello World</p>
    <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
  </body>
</html>

Jinja는 또한 Python의 고급 구조를 제공하므로 다음과 같이 단축 할 수 있습니다.

<html>
<head>
  <script>
    var myGeocode = [{{ ', '.join(geocode) }}];
  </script>
</head>
<body>
  <p>Hello World</p>
  <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
</body>
</html>

for루프, if문 등을 사용할 수도 있습니다. 자세한 내용은 Jinja2 문서 를 참조하세요.

또한 Jinja2의 표준 필터 세트에tojson 추가 된 필터를 지적하는 Ford의 답변을 살펴보십시오 .

2018 년 11 월 편집 : tojson이제 Jinja2의 표준 필터 세트에 포함됩니다.


답변

거의 모든 Python 객체를 JavaScript 객체로 가져 오는 이상적인 방법은 JSON을 사용하는 것입니다. JSON은 시스템 간 전송을위한 형식으로 훌륭하지만 때때로 JavaScript Object Notation을 의미한다는 사실을 잊어 버립니다. 즉, JSON을 템플릿에 주입하는 것은 객체를 설명하는 JavaScript 코드를 주입하는 것과 같습니다.

Flask는이를 위해 Jinja 필터를 제공 tojson합니다. 구조를 JSON 문자열로 덤프하고 Jinja가 자동 이스케이프하지 않도록 안전하다고 표시합니다.

<html>
  <head>
    <script>
      var myGeocode = {{ geocode|tojson }};
    </script>
  </head>
  <body>
    <p>Hello World</p>
    <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
  </body>
</html>

이것은 JSON 직렬화 가능한 모든 Python 구조에서 작동합니다.

python_data = {
    'some_list': [4, 5, 6],
    'nested_dict': {'foo': 7, 'bar': 'a string'}
}
var data = {{ python_data|tojson }};
alert('Data: ' + data.some_list[1] + ' ' + data.nested_dict.foo +
      ' ' + data.nested_dict.bar);


답변

사용하여 데이터 속성을 HTML 요소에하는 회전 수단에 사용할 수있는 인라인 스크립트 사용하는 것을 피한다 엄격한 CSP 규칙을 보안을 강화합니다.

다음과 같이 데이터 속성을 지정하십시오.

<div id="mydiv" data-geocode='{{ geocode|tojson }}'>...</div>

그런 다음 다음과 같이 정적 JavaScript 파일에서 액세스합니다.

// Raw JavaScript
var geocode = JSON.parse(document.getElementById("mydiv").dataset.geocode);

// jQuery
var geocode = JSON.parse($("#mydiv").data("geocode"));


답변

또는 변수를 반환하는 엔드 포인트를 추가 할 수 있습니다.

@app.route("/api/geocode")
def geo_code():
    return jsonify(geocode)

그런 다음 XHR을 수행하여 검색합니다.

fetch('/api/geocode')
  .then((res)=>{ console.log(res) })


답변

플라스크를 사용하여 공급되는 스크립트에 변수를 전달하려는 사람들을위한 또 다른 대안으로, 외부 변수를 정의한 다음 스크립트를 다음과 같이 호출하여이 작업을 수행 할 수있었습니다.

    <script>
    var myfileuri = "/static/my_csv.csv"
    var mytableid = 'mytable';
    </script>
    <script type="text/javascript" src="/static/test123.js"></script>

진자 변수를 입력하면 test123.js작동하지 않고 오류가 발생합니다.


답변

작업 답변은 이미 제공되었지만 플라스크 변수를 사용할 수없는 경우 안전 장치 역할을하는 검사를 추가하고 싶습니다. 사용할 때 :

var myVariable = {{ flaskvar | tojson }};

변수가 존재하지 않게하는 오류가있는 경우 결과 오류로 인해 예기치 않은 결과가 발생할 수 있습니다. 이를 방지하려면 :

{% if flaskvar is defined and flaskvar %}
var myVariable = {{ flaskvar | tojson }};
{% endif %}


답변

<script>
    const geocodeArr = JSON.parse('{{ geocode | tojson }}');
    console.log(geocodeArr);
</script>

이것은 jinja2를 사용하여 지오 코드 튜플을 json 문자열로 변환 한 다음 자바 스크립트 JSON.parse가이를 자바 스크립트 배열로 변환합니다.