如果你的页面存在POST请求,如果不注释掉settings.py文件中的django.middleware.csrf.CsrfViewMiddleware,会直接出现403错误,那么现在打开它,做一下测试,看是否出现错误。
这其实是django内部帮我们做的一次防护,get请求没有限制,post请求的时候django会先去找csrf生成的随机字符串,现在是没有的,django没找到就会报错。既然django需要这个随机字符串,我们给它就是了。可以在login.html模板中form表单里面添加:{{ csrf_token }}
,然后再次尝试,你就会在登录页面看到django帮我们生成的随机字符串,但是一般不会让这个随机字符串显示在页面中,可以修改为:{% csrf_token %}
,这样django会将这个随机字符串放在html的value属性中,页面是看不到,在我们呢后台可以拿到这个随机字符串,然后我们带着这个随机字符串去发送POST请求。
在Cookie中会存在一个csrftoken,两者是一样的,我们的后台也可以从cookie中取它。做一个简单的例子,这里还是需要jquery.js和jquery.cookie.js,没有的下载即可。
那么你可能需要知道django.middleware.csrf.CsrfViewMiddleware做了什么事情,这个可以导入查看一下源代码,就像这样:from django.middleware.csrf import CsrfViewMiddleware,你就随便看看,有没有什么发现,大约在304行出现了下面的代码,我只截取一部分,就在process_view函数中:
request_csrf_token = ""
if request.method == "POST":
try:
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
except OSError:
# Handle a broken connection before we've completed reading
# the POST data. process_view shouldn't raise any
# exceptions, so we'll ignore and serve the user a 403
# (assuming they're still listening, which they probably
# aren't because of the error).
pass
if request_csrf_token == "":
# Fall back to X-CSRFToken, to make things easier for AJAX,
# and possible for PUT/DELETE.
request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')
request_csrf_token = _sanitize_token(request_csrf_token)
if not _compare_salted_tokens(request_csrf_token, csrf_token):
return self._reject(request, REASON_BAD_TOKEN)
现在我们可以把目光放在settings.CSRF_HEADER_NAME上,这个是什么,我们可以打印一下,采用下面的代码:
def login(request):
from django.conf import settings
print(settings.CSRF_HEADER_NAME) #HTTP_X_CSRFTOKEN
if request.method=='GET':
return render(request,'login.html')
if request.method=='POST':
pass
可以看到在控制台输出了HTTP_X_CSRFTOKEN,这其实就是请求头中的信息,也就是说HTTP_X_CSRFTOKEN对应的值是token,但是请求头真实的名字叫:X-CSRFtoken,怎么知道的呢,还是做一下测试,使用ajax发送post请求的时候带上一个headers就可以了,假设设置一个kkkkkkkkkkkk的请求头,看一下结果是什么:

可以看到django在自动在请求头上添加一个HTTP,所以说HTTP_X_CSRFTOKEN的真实值是X-CSRFtoken,那么现在就知道该如何添加请求头的信息了,代码参考:
<script type="text/javascript" src="/static/jquery-3.4.1.js"></script>
<script type="text/javascript" src="/static/jquery.cookie.js"></script>
<script>
$(function () {
var csrftoken=$.cookie('csrftoken');
console.log(csrftoken);
$('#bt').click(function () { {# 绑定事件,发送ajax请求 #}
$.ajax({
url:'/login/',
type:'POST',
data:{'user':'root','pwd':'123'},
headers:{'X-CSRFtoken':$.cookie('csrftoken')}, {# 从cookie中获取csrftoken #}
success:function (data) {
}
})
})
})
</script>
需要注意的是请求头信息,为什么不是X_CSRFTOKEN呢?因为在django中不允许出现_,允许使用-来代替,所以我们设置的是X-CSRFtoken。这样一来我们打开settings.py中的csrf呢一行,测试一下代码是否可以发送POST请求,结果肯定是可以的,这里不再做演示了!
使用form表单发送post请求和使用ajax发送post请求都是类似的,重点就是这个csrftoken去哪里获取。现在我需要把所有的ajax请求都加上这个headers,我们使用上面的方法会有点麻烦,可以使用ajax为我们提供的方法:
<script type="text/javascript" src="/static/jquery-3.4.1.js"></script>
<script type="text/javascript" src="/static/jquery.cookie.js"></script>
<script>
$(function () {
{# xhr :是xmlHttpRequest 对象#}
$.ajaxSetup({
beforeSend:function (xhr,settings) { {# 在发送之前会先执行这个函数 全局配置 #}
xhr.setRequestHeader('X-CSRFtoken',$.cookie('csrftoken')) ; {# 设置请求头 #}
}
});
$('#bt').click(function () { {# 绑定事件,发送ajax请求 #}
$.ajax({
url:'/login/',
type:'POST',
data:{'user':'root','pwd':'123'},
success:function (data) {
}
})
})
})
</script>
那么这样对于GET请求也会添加上请求头,我们不想添加的话,可以在内部做一个判断,只对POST请求添加headers:
<script>
$(function () {
function csrfSafeMethod(method){
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
} {# 通过这个函数进行判断 #}
$.ajaxSetup({
beforeSend:function (xhr,settings) { {# 在发送之前会先执行这个函数 全局配置 #}
if (!csrfSafeMethod(settings.type) && !this.crossDomain) { {# 通过settings.type拿到提交的方式 #}
xhr.setRequestHeader('X-CSRFtoken',$.cookie('csrftoken')) ; {# 设置请求头 #}
}
}
});
$('#bt').click(function () { {# 绑定事件,发送ajax请求 #}
$.ajax({
url:'/login/',
type:'POST',
data:{'user':'root','pwd':'123'},
success:function (data) {
}
})
})
})
</script>
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!