通过Django将Python数据传递给JavaScript
通过Django将Python数据传递给JavaScript
我正在使用Django和Apache来提供网页服务。我的JavaScript代码目前包含一个数据对象,其中包含根据用户从菜单中选择的选项在各种HTML小部件中显示的值。我希望从Python字典中派生这些数据。我想我知道如何将JavaScript代码嵌入到HTML中,但是如何将数据对象嵌入到该脚本中(即时)以便脚本的函数可以使用它呢?\n换句话说,我想从Python字典创建一个JavaScript对象或数组,然后将该对象插入到JavaScript代码中,然后将该JavaScript代码插入到HTML中。\n我想这种结构(例如,在JavaScript代码中嵌入变量的数据)可能不是最佳选择,但作为一个新手,我不知道其他的替代方法。我看过Django序列化函数的文章,但在我能将数据放入我的JavaScript代码之前,这些函数对我没有帮助。\n我目前还没有使用像jQuery这样的JavaScript库。
问题的原因是在Django中将Python数据传递给JavaScript时,需要将Python数据转换为JSON格式。然而,在转换过程中,需要注意Django的自动转义机制,以防止潜在的安全问题。解决方法是使用Python的JSON模块将数据转换为JSON格式,并在模板中使用safe
过滤器或autoescape
标签的off
选项来阻止自动转义。
首先,在视图中,可以使用Python的JSON模块将字典数据转换为JSON格式,并将其添加到上下文中。代码如下:
import json def get_context_data(self, **kwargs): context['my_dictionary'] = json.dumps(self.object.mydict)
然后,在模板中,可以像下面这样将JSON数据传递给JavaScript变量:
<script> my_data = {{ my_dictionary|safe }}; </script>
需要注意的是,json.dumps
方法不会转义斜杠(forward slashes),这可能会导致安全问题。因此,在转换数据时,需要注意防止潜在的攻击。例如,存在以下潜在攻击代码:{'</script><script>alert(123);</script>': ''}
。为了解决这个问题,可以参考其他答案中的方法,提供一个修复方案。
总结起来,要在Django中将Python数据传递给JavaScript,需要将数据转换为JSON格式,并在模板中使用safe
过滤器或autoescape
标签来阻止自动转义。这样可以确保数据传递的安全性。
问题的出现原因:
在使用Django将Python数据传递给JavaScript时,可能会遇到问题。在模板中渲染json对象时,需要确保在安全模式下进行渲染。如果数据中包含</script>
字符串,会导致渲染出现问题。
解决方法:
可以通过在模板中手动设置安全模式来解决该问题。以下是一个示例代码:
<script type="text/javascript"> data_from_django = {{ my_data|safe }}; widget.init(data_from_django); </script>
上述代码片段将从Django传递的数据赋值给JavaScript变量data_from_django
,并将其传递给widget.init()
函数进行处理。通过使用|safe
过滤器,确保在模板中渲染json对象时不会出现问题。
在处理这个问题后,以下是一个修复漏洞的答案示例。
希望以上内容能帮到有类似问题的人。
Passing Python Data to JavaScript via Django
在Django模板中放置大量的JavaScript代码是不推荐的,这样很难编写和调试,特别是当项目扩展时。相反,可以尝试将所有JavaScript代码写在一个独立的脚本文件中,然后在模板中加载这个文件,同时在模板中只包含一个JSON数据对象。这样做可以使您能够通过类似于JSLint的工具运行整个JavaScript应用程序,对其进行缩小,并且可以在不依赖于Django应用程序的任何依赖项的情况下使用静态HTML文件进行测试。使用simplejson这样的库还可以节省编写乏味的序列化代码的时间。
如果您不假设正在构建一个AJAX应用程序,可以按照以下方式完成:
在视图中:
from django.utils import simplejson def view(request, …): js_data = simplejson.dumps(my_dict) … render_template_to_response("my_template.html", {"my_data": js_data, …})
在模板中:
需要注意数据的类型:如果`my_data`是一个简单的数字或来自受控源的字符串(不包含HTML),例如格式化的日期,则不需要特殊处理。如果可能由用户提供不受信任的数据,您需要使用类似于`escape`或`escapejs`过滤器对其进行清理,并确保您的JavaScript安全处理数据以避免跨站脚本攻击。
至于日期,您可能还需要考虑如何传递日期。我几乎总是发现将它们作为Unix时间戳进行传递最容易:
在Django中:
time_t = time.mktime(my_date.timetuple())
在JavaScript中,假设您使用了上面片段的结果:
my_date = new Date(); my_date.setTime(time_t*1000);
最后,注意UTC - 您应该让Python和Django日期函数在UTC中交换数据,以避免用户本地时间的尴尬偏移。
2018年更新:我仍然喜欢使用JSON传递复杂的值,但在过去的十年中,HTML5数据API已经获得了几乎普遍的浏览器支持,它非常方便传递简单(非列表/字典)的值,特别是如果您可能希望根据这些值应用CSS规则,并且不关心不受支持的Internet Explorer版本。
…let myWidget = document.getElementById("my-widget"); console.log(myWidget.dataset.viewMode); // Prints tabular somethingElse.addEventListener('click', evt => { myWidget.dataset.viewMode = "list"; });
这是一种很好的方法,可以将数据暴露给CSS,如果您希望在Django模板中设置初始视图状态,并且当JavaScript更新`data-`属性时自动更新它。我将其用于诸如在用户选择要处理的内容之前隐藏进度小部件,或者根据获取结果有条件地显示/隐藏错误,甚至像使用CSS显示活动记录计数一样的东西,例如`#some-element::after { content: attr(data-active-transfers); }`。
评论区的一些人还提到了一些关于安全性的问题,比如在将JSON直接解析到HTML中是否存在安全问题,以及如何对数据进行清理和转义以避免潜在的攻击。他们建议在渲染数据时使用`|safe`过滤器进行数据清理。