我的 django 模板布尔变量在 javascript 中没有按预期工作

Posted

技术标签:

【中文标题】我的 django 模板布尔变量在 javascript 中没有按预期工作【英文标题】:My django template boolean variable isn't working as expected in javascript 【发布时间】:2012-09-05 21:51:01 【问题描述】:

这是我的 base.html 标头中的代码

    <script>
        var auth_status = " user.is_authenticated "
    </script>

    % block scripts %  % endblock %

我网站中的其余脚本都在块脚本中。

在子模板中(在脚本块内和脚本标签内)我有这段代码,

         if (auth_status) 
          //something
         

手头的错误是 auth_status 始终为 True,它应该在何时打开和关闭取决于用户是否登录。Request_context 正在传递给模板,因此这不应该是错误。

谢谢

【问题讨论】:

与您的问题看似无关,但请注意,如果您确实依赖此 JS 变量的值,则执行 if (user_is_authenticated) do stuff; 可能会成为安全问题。用户可以在执行前修改 JS 变量的值。 所以你说用户可以以某种方式设置auth_status = true?那么绕过 js var 是一个有效的解决方法吗?例如:if( user.is_authenticated|yesno:"true,false" ) 与 if(auth_status) ?? 恶意用户可能只是拉取您页面的源代码,然后用...替换他们想要的任何内容。 没有方法可以实现任何安全客户端(即在JS中)并且没有没有解决方法,所有安全/访问控制必须在服务器端(即在您的 Python 代码中)完成。 JS 不是动态执行的应用程序代码的扩展,它是不同的东西,具有不同的约束。 等等,所以即使是 django 的模板变量也有被人篡改的风险?一个合理的解决方案是让任何需要 user_auth 成为 html POST 的东西? 是的,您可以在 python 代码中安全地使用request.user.is_authenticated()。可以在模板代码中使用% if user.authenticated %,因为这将在服务器端计算,即在 HTML 发送到客户端之前。一般的经验法则是可以更改到达客户端的任何内容,而无法更改的内容则不能。 (至少,不是这样;)) 【参考方案1】:

另一种选择是使用 jinja2 tojson 过滤器:

<script>
  let javascript_var =  python_var|tojson ;
</script>

您可能还想使用 safe 过滤器,具体取决于您传递的内容:

<script>
  let javascript_var =  python_var|tojson|safe ;
</script>

【讨论】:

【参考方案2】:

我看到你的auth_status 变量似乎是一个字符串,而不是一个布尔值。 javascript 上具有非空字符串的变量将在 if 子句上计算为 true

总之,像

<script>
    var auth_status =  user.is_authenticated ;
</script>

不会工作,因为这会生成这个 HTML:

<script>
    var auth_status = True;
</script>

因为 Python 的 True 布尔值是大写的。

这应该完成从 Python 到 Javascript 的翻译:

<script>
    var auth_status =  user.is_authenticated|yesno:"true,false" ;
</script>

在此处查看 yesno 文档:https://docs.djangoproject.com/en/dev/ref/templates/builtins/#yesno

【讨论】:

哇!非常感谢,我完全忽略了两种语言的大写/小写差异! 将 Python 变量传递给 JS 变量的更通用的解决方案是使用 json。在 py 中:上下文 ['foo'] = json.dumps(a_py_list)。在模板 中。这适用于大多数数据结构,也适用于布尔值。 @Sean 我不认为在您第一次将值放入 context 时使用 json 将 Python 值转储到 Javascript 安全的表示中是一个好主意,因为您例如,在处理程序中不能确定它是用作 JS 值还是用作 Jinja 模板中的 Python。如果在我的 Jinja 模板中我想使用像 % if myBool % 这样的代码,如果 myBool 具有字符串值而不是 Python 布尔值,它将无法正常工作。 @Jesse:我没想到会有混淆,但你是对的。我应该澄清一下,我只对 JS 中需要的变量执行此操作,而不是上下文中的所有变量。通常它是将更复杂的数据聚合到单个字典中,在 JS 中它成为一个对象。您是否知道另一种解决在初始页面加载时将后端变量传递给 JS 的一般问题的方法?不是 ajax 应用程序,只是一次加载,然后是一些需要使用来自服务器的数据进行初始化的 JS。

以上是关于我的 django 模板布尔变量在 javascript 中没有按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义模板中使用 Django 的管理员布尔图标?

布尔值的 Django 模板标签

Django 模板自定义标签为布尔值

Django:如何在模板的 if 语句中使用变量?

来自 django 基本模板文件中 url 的变量

针对特定类型的所有变量的 django 模板过滤器