Get实现的效果图如下:
POST实现的效果图如下:
Django代码部分
urls.py代码:
需要配置两个URL地址,一个作为渲染HTML使用,一个作为Ajax返回JSON数据使用.
from .views import index, index_ajax
urlpatterns = [
# 首页
path('', index, name='index'),
path('index_ajax', index_ajax, name='index_ajax'),
]
views.py使用代码:
需要配置两个函数,一个函数作为渲染HTML使用,一个作为Ajax返回JSON数据使用.
def index(request):
return render(request, 'index.html')
def index_ajax(request):
from django.http import JsonResponse
import json
# Ajax的POST响应
if request.method == "POST":
"""
通过打印request.POST
print(request.POST)
print(type(request.POST))
看到的数据格式如下:
<QueryDict: {'post_ajax_user': ['{"name":"qunbin"}']}>
<class 'django.http.request.QueryDict'>
"""
# 获取字典Key为:post_ajax_user,对应的值:
post_ajax_user = request.POST['post_ajax_user']
# 由于在前台,把字典转换成字符串了,所以这里还需要把字符串转换为字典:
get_ajax_dict = json.loads(post_ajax_user)
# 获取字典里key为:name,对应的值:
get_user = get_ajax_dict["name"]
# 查询结果为QuerySet
user = User.objects.filter(username=get_user)
if not user:
return JsonResponse({"result": "您要查询的信息不存在."})
else:
context = {}
context["result"] = "您要查询的用户存在"
context["email"] = user[0].email # 因为查询结果是QuerySet,所以这里要加[0].
return JsonResponse(context)
# Ajax的GET响应
else:
# 获取所有用户信息,查询结果为QuerySet
all_users = User.objects.all()
# 用于存储用户的列表
users = []
for user in all_users:
# 遍历QuerySet的用户名,并将用户名添加到users列表里
users.append(user.username)
context = {}
context["user"] = users
return JsonResponse(context)
如果要关闭函数的csrf保护功能,使用如下命令操作(不推荐关闭csrf保护):
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt # 取消CSRF的保护,不推荐取消保护
def index_ajax(request):
html渲染文件代码如下:
一定要注意,要:
var request = new XMLHttpRequest();
这里一定要加new 一定要加new 一定要加new.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
window.onload = function () {
var get_ajax = document.getElementById('get_ajax');
var post_ajax = document.getElementById('post_ajax');
var show_area = document.getElementById('show_area');
get_ajax.onclick = function () {
var request = new XMLHttpRequest();
url = this.href;
request.open('GET', url);
request.send(null);
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200){
resultDict = JSON.parse(request.responseText);
console.log(resultDict);
result = resultDict.user;
console.log(result);
for (var i=0; i<result.length; i++) {
//第一行这里不能用 +=,否则每次点击内容会不断累加,后面的可以用+=,否则后面的内容会把前面内容覆盖了.
show_area.innerHTML += result[i] + "<br>"
}
// show_area.innerText = result.user;
}
};
return false;
};
post_ajax.onclick = function () {
var request = new XMLHttpRequest();
//获取要查询的用户
var look_user = document.getElementById('look_user').value;
//POST的URL地址,获得父类的action属性URL值
var url = this.parentNode.action;
request.open('POST', url);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
// 把csrf_token值,发送给Django.否则,只能在views.py对应的ajax函数里,使用@csrf_exempt取消csrf保护.
// 下面代码用来取csrftoken的值:
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
// 把获得到的值,添加到setRequestHeader,发送给Django
request.setRequestHeader("X-CSRFToken",csrftoken);
//这里的"user"作为后台接受字典key值.
// request.send("user=" + look_user);
//如果要发送多个数据给后台,可以通过字典发送
var test = {
"name": look_user
};
/*
由于send(),只能接受字符串,所以要使用JSON.stringify,把字典转换成字符串后在传输.
在后台打印request.POST,看到的数据为:<QueryDict: {'post_ajax_user': ['{"name":"qunbin"}']}>
由于把字典转换成了字符串,所以后台还需要把字符串转换成字典.
*/
request.send("post_ajax_user=" + JSON.stringify(test));
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200){
var resultDict = JSON.parse(request.responseText);
//第一行这里不能用 +=,否则每次点击内容会不断累加,后面两个必须要用+=,否则后面的内容会把前面内容覆盖了.
show_area.innerText = resultDict.result;
show_area.innerHTML += "<br>";
// show_area.innerText += "它的邮箱是:" + resultDict.email;
// 如果有这个属性就展示.
if (resultDict.email){
show_area.innerText += "它的邮箱是:" + resultDict.email;
}
}
};
return false;
};
}
</script>
</head>
<body>
<div>
<span>欢迎访问</span>    <span><a href="{% url 'students' %}">点击进入</a></span>
<br>
<a id="get_ajax" href="{% url 'index_ajax' %}">通过get获取ajax,所有系统上的账号</a>
</div>
<hr>
<div>
<!--
使用post方法提交数据到后台,如果页面没有做跨站伪造,则会被浏览器拒绝访问
使用Ajax的POST,在form下面加csrf_token,提交POST时,并不会把csrftoken值,发送给Django,因此需要借助JS把token值发送给Django
如果不在JS里将token值发送Django,要在urls.py或views.py对应ajax函数里,使用 @csrf_exempt,取消CSRF的保护.不建议取消csrf保护
-->
<form action="{% url 'index_ajax' %}" method="post">
<!-- 如果HTML文件中没有包含 csrf_token , Django不会为这个页面设置csrftoken的cookie值。-->
{% csrf_token %}
<input id="look_user" type="text" name="user">
<br>
<!-- 下面这两条注释的a元素和input标签,也都可以代替button元素使用.这里可以不用form表单,但建议使用form表单来做.-->
<!-- <a id="post_ajax" href="{% url 'index_ajax' %}">通过POST,查询输入用户信息.</a>-->
<!-- <input id="post_ajax" type="submit" value="通过POST,查询输入用户信息.">-->
<button id="post_ajax" type="submit">通过POST,查询输入用户信息.</button>
</form>
</div>
<div>
<span>显示区域</span>
<p id="show_area"></p>
</div>
</body>
</html>
注意事项:
1 如果使用从cookie中取csrftoken的方式,需要确保cookie存在csrftoken值。
如果你的视图渲染的HTML文件中没有包含{% csrf_token %}, Django可能不会设置CSRFtoken的cookie。
这个时候需要使用ensure_csrf_cookie()装饰器强制设置Cookie。
django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def login(request):
pass
2 使用Ajax的POST,在form下面加csrf_token,提交POST时,并不会把csrftoken值,发送给Django,因此需要借助JS把token值发送给Django 如果不在JS里将token值发送Django,要在urls.py或views.py对应ajax函数里,使用 @csrf_exempt,取消CSRF的保护.不建议取消csrf保护
3 为了通过csrf的安全检查,在前端页面通过JS函数,提取csrftoken值后,发给django,相关代入如下:
// 把csrf_token值,发送给Django.否则,只能在views.py对应的ajax函数里,使用@csrf_exempt取消csrf保护.
// 下面代码用来取csrftoken的值:
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
// 把获得到的值,添加到setRequestHeader,发送给Django
request.setRequestHeader("X-CSRFToken",csrftoken);
4 在Django的views.py里,针对login(没有做Ajax)打印request.POST,可以看到html的form,把csrf_token值发送到后台了.因此在form下面添加{% csrf_token %},既可以让Django后台产生Cookie,同时form表单在提交时,会把csrf_token值发送到后台(这里所介绍的,是指在没有做Ajax情况下).
<QueryDict: {'csrfmiddlewaretoken': ['EJAdbZu5HIaSUsNkOmQG6foNcLrv5Nm9Ft0ai6SD4dqEMtQX3lWshFiQXBUzHPJ0'], 'username': ['bruce'], 'password': ['XXXX保密'], 'valid_num': ['1iTR']}>
游览器打开html页面后,查看源码,可以看到{% csrf_token %}渲染成如下代码:
<form action="#" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="A2Xl6WXZJGJHspu1LPbgM0EqC9IgVHtj7kGiS1VPFVU7k6urXh75BcP7HEFDSJWl">