如何在 Javascript 生成的 HTML 表单中包含 Django 1.2 的 CSRF 令牌?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3764589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I include Django 1.2's CSRF token in a Javascript-generated HTML form?
提问by Huuuze
I recently upgraded to Django 1.2.3 and my upload forms are now broken. Whenever I attempt to upload, I receive a "CSRF verification failed. Request aborted." error message.
我最近升级到 Django 1.2.3,我的上传表单现在坏了。每当我尝试上传时,我都会收到“CSRF 验证失败。请求中止”。错误信息。
After reading Django's documentationon this subject, it states that I need to add the {% csrf_token %} template tag within the HTML <form>in my template. Unfortunately, my <form>is generated via JavaScript (specifically, ExtJs's "html" property on a Panel).
在阅读了关于这个主题的Django 文档后,它指出我需要<form>在我的模板的 HTML中添加 {% csrf_token %} 模板标签。不幸的是,我<form>是通过 JavaScript 生成的(特别是面板上 ExtJs 的“html”属性)。
Long story short, how do I add the required CSRF token tag to my <form>when my <form>is not included in a Django template?
长话短说,<form>当我<form>的未包含在 Django 模板中时,如何将所需的 CSRF 令牌标签添加到我的?
回答by chrisv
Another option would be to adapt the cookie/header based solution shown in the Django docswith Ext - preferable if you have a lot of templates and don't want to change every single one.
另一种选择是使用 Ext调整 Django 文档中显示的基于 cookie/header 的解决方案- 如果您有很多模板并且不想更改每个模板,则更可取。
Just drop the following snippet in your overrides.js (or wherever you put global modifications):
只需将以下代码段放入您的 overrides.js(或您放置全局修改的任何位置):
Ext.Ajax.on('beforerequest', function (conn, options) {
if (!(/^http:.*/.test(options.url) || /^https:.*/.test(options.url))) {
if (typeof(options.headers) == "undefined") {
options.headers = {'X-CSRFToken': Ext.util.Cookies.get('csrftoken')};
} else {
options.headers.extend({'X-CSRFToken': Ext.util.Cookies.get('csrftoken')});
}
}
}, this);
(edit: Ext already has cookie reading function, no need to duplicate it)
(编辑:Ext已有cookie读取功能,无需复制)
回答by matt snider
The easiest way is to create a hidden form on your page using django that doesn't do anything. Then use JavaScript to fetch the form and specifically the token input out of the form. Lastly, insert or copy that token input into the form you are dynamically generating.
最简单的方法是使用 django 在你的页面上创建一个隐藏的表单,它什么都不做。然后使用 JavaScript 获取表单,特别是从表单中获取令牌输入。最后,将该令牌输入插入或复制到您动态生成的表单中。
Here are two examples of how you might publish the token for JavaScript.
以下是您可以如何发布 JavaScript 令牌的两个示例。
<input id="csrf_token" value="{{ csrf_token }}"/>
<script type="text/javascript">
var CSRF_TOKEN = document.getElementById('csrf_token').value;
</script>
or
或者
<script type="text/javascript">
var CSRF_TOKEN = "{{ csrf_token }}";
</script>
回答by fatgeekuk
A better solution is to generate the code of the js file from a view/template.
更好的解决方案是从视图/模板生成 js 文件的代码。
Then, in the view you can set the csrf token up in the context like so...
然后,在视图中,您可以像这样在上下文中设置 csrf 令牌......
from django.core.context_processors import csrf
context = RequestContext(request)
context.update(csrf(request))
Then, in the template, you can use {{ csrf_token }}to get the raw value of the csrf token, and then use that to build a hidden field into your form with the name csrfmiddlewaretoken.
然后,在模板中,您可以使用{{ csrf_token }}获取 csrf 令牌的原始值,然后使用它在表单中构建一个名称为 的隐藏字段csrfmiddlewaretoken。
回答by Manoj Govindan
Does the view you are POSTing to also respond to GET? In that the JS code can make a GETrequest to the view in question and parse the output to extract the CSRF token. My JS-fu is weak and I am not sure how best you can do the parsing from the client side.
您POST要回应的观点是否也有回应GET?因为 JS 代码可以GET向相关视图发出请求并解析输出以提取 CSRF 令牌。我的 JS-fu 很弱,我不确定从客户端进行解析的效果如何。
For a broadlyrelated example see this question. In this case the user was attempting to POSTusing a Python script and failing for the same reason. The solution was the same, except he had to do it from a Python script rather than JavaScript.
有关广泛相关的示例,请参阅此问题。在这种情况下,用户试图POST使用 Python 脚本并由于同样的原因失败。解决方案是一样的,只是他必须从 Python 脚本而不是 JavaScript 来完成。
回答by Dave
This may not be ideal, but it was the fastest solution for me. In my main template at the bottom of the "body", I added a javascript function to my library.
这可能并不理想,但对我来说这是最快的解决方案。在“主体”底部的主模板中,我向库中添加了一个 javascript 函数。
<script type="text/javascript">
MyToolkit.Utils.getCSRFToken = function () {
return "{% csrf_token %}";
};
</script>
回答by Collin Anderson
This will use the csrf token or auto generate a new one if needed. It will handle all form submits on the page. If you have off-site forms you'll need to make sure they don't run this code.
如果需要,这将使用 csrf 令牌或自动生成一个新令牌。它将处理页面上的所有表单提交。如果您有场外表单,则需要确保它们不运行此代码。
<script>
$(document).on('submit', 'form[method=post]', function(){
if(!document.cookie.match('csrftoken=([a-zA-Z0-9]{32})')) {
for(var c = ''; c.length < 32;) c += 'abcdefghijklmnopqrstuvwxyz'.charAt(Math.random() * 26)
document.cookie = 'csrftoken=' + c + '; path=/'
}
if(!this.csrfmiddlewaretoken) $(this).append('<input type="hidden" name="csrfmiddlewaretoken">')
$(this.csrfmiddlewaretoken).val(document.cookie.match('csrftoken=([a-zA-Z0-9]{32})')[1])
})
</script>
requires jQuery 1.7+
需要 jQuery 1.7+

