繁体   English   中英

将上下文变量从模板传递到 JavaScript 文件

[英]Passing context variable from template to JavaScript file

这个线程在这里使用内嵌JavaScript变量在模板中进行讨论。 如果我有包含脚本的单独.js文件,位于static文件夹中,例如:

utils.js

const createButton = (buttonCount) => {
    containerId = "myContainerId"
    container = document.getElementById(containerId)
    for (var i = 0; i < buttonCount; i++) {}
        newButton = document.createElement("button")
        newButton.value = "Test"
        newButton.id = "testButton" + i
        container.appendChild(newButton)
    }
}

createButton(buttonCount)

mytemplate.html

{% extends "base.html" %}
{% load static %}

{% block title %}Testpage{% endblock %}


{% block content-main %}
  <link href="{% static "css/mycss.css" %}" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.0/css/bulma.css" /> 

  <div id="myContainerId"></div>

  <script src="{% static 'js/utils.js' %}"> </script>

{% endblock %}

如果我有一个变量buttonCount通过视图函数的上下文传递到这个模板,我如何将它传递给函数createButton()调用的utils.js文件?

views.py

def button_view(request):
    ...
    buttonCount = 5
    return render(request, 'mytemplate.html', {'buttonCount': buttonCount})

可以有以下几种方式:

  • 使用输入字段

    <input id="buttonCount" value = "{{buttonCount}}" style="display:none;">

然后读取 utils.js 中 id= buttonCount 元素的值。

  • 内联脚本** 不建议使用 Document.onload 代替。

     <script> set_button_count({{buttonCount}}); </script>

但这会在您的 utils.js 尚未加载时产生问题。

  • document.onload将脚本源码放在<head></head>

    <script src="{% static 'js/utils.js' %}" defer> </script>
    <script>
    document.addEventListener('onload',function(
    {set_button_count({{buttonCount}});
    })
    </script>

  1. set_button_count() 将被放置在 utils.js
  2. Defer 将要求浏览器仅在 utils.js 完成时才触发文档加载,并且将在文档加载后获取和加载。

警告:内联脚本将与严格的 CSP(内容安全策略)一起使用。任何内联脚本都可以提供一个src作为nonce CSP 可以在 apache 或 Nginx 的服务器端完成,它们是非常常见的 Web 服务器/反向代理,或者如果您无法控制,您也可以在 HTML 中提及相同的内容。


<meta http-equiv="Content-Security-Policy" 
        content="default-src 'self';
        script-src 'self' 'nonce-{{nonce}}';">

这个nonce可以像这样生成:


    import random,base64
    
    def usersession_processor(request):
        user = request.user
        unbaked_nonce = '%32x' % random.getrandbits(16*8)
        unbaked_nonce = unbaked_nonce.encode('utf-8')
        baked_nonce = base64.b64encode(unbaked_nonce)
        baked_nonce = baked_nonce.decode('utf-8')

然后<script src="{{nonce}}"></script>可以用于安全的内联。

我不认为这是推荐的,但是如果您使用 django 模板上下文,您可以做这样的事情。 将脚本放在页面底部,并将 buttoncount 作为 Django 模板语言变量包含在内。 不过,我认为不建议将 Django 模板变量与 javascript 混合使用。

你可以在你的 'base.html' 文件中放置一个新块,在 body 标签的底部,如下所示:

{% block inline_javascript %}
{% enblock inline_javascript %}

然后在您希望该函数在其上运行的页面内,将脚本放在该页面底部“块内容”之外的相同标签内,例如:

{% block inline_javascript %}
    <script>
        const createButton = ({{ buttonCount }}) => {
            containerId = "myContainerId"
            container = document.getElementById(containerId)
            for (var i = 0; i < {{ buttonCount }}; i++) {}
                newButton = document.createElement("button")
                newButton.value = "Test"
                newButton.id = "testButton" + i
                container.appendChild(newButton)
            }
        }
    </script>
{% enblock inline_javascript %}

暂无
暂无

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

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