一.ajax简介
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
二.异步加载
以知乎为例,我们没有输入验证码或者输入错误的验证码之后页面会提示请输入验证码,但是这个时候页面缺没有刷新,但是实际上数据已经到后台进行校验过了。
其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。
- 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
- 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
ajax优点:
1.AJAX使用JavaScript技术向服务器发送异步请求;
2.AJAX请求无须刷新整个页面;
3.因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;
写一个登录的示例:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>ajax</h1>
<form action="" method="post">
{% csrf_token %}
<div>
用户名:<input type="text" name="username" id="username">
</div>
<div>
密码:<input type="password" name="password" id="password">
</div>
<div>
<input type="button" id="btn" value="确认"> #button就是一个单纯的按钮 不会触发form表单请求
{# <input type="submit" id="btn" value="确认">#} #submit会提交请求
</div>
</form>
<script src="{% static 'jquery.js' %}"></script>
<script>
$('#btn').click(function () { #绑定事件
$.ajax({ #jQuery对象调用ajax
url:"{% url 'app03:login' %}",
type:'get',
success:function (res) {
console.log(res)
}
})
})
</script>
</body>
</html>
后端代码:
def login(request):
if request.method == 'GET':
return render(request,'manytable/login.html')
else:
uname = request.POST.get('username')
pwd = request.POST.get('paddword')
if uname == 'test' and pwd == '123':
return redirect('app03:show_book')
else:
return redirect('app03:login')
这里后端返回的是一大串字符串:
我们后端返回一个页面没有意义,就是一堆的字符串,拿到了这个页面,怎么处理,要做什么事情,我们要根据返回的结果做一些事情才有意义,后端就需要进行数据的加工:
import json
def login(request):
if request.method == 'GET':
return render(request,'manytable/login.html')
else:
uname = request.POST.get('username')
pwd = request.POST.get('paddword')
if uname == 'test' and pwd == '123':
# return redirect('app03:show_book')
ret = {'code':0,'success':'/app03/show_book/'} #需要返回字典数据
return HttpResponse(json.dumps(ret)) #这里需要序列化成json对象 方便前端解析
else:
# return redirect('app03:login')
ret = {'code':1,'fail':'/app03/login/'}
return HttpResponse(json.dumps(ret))
html文件中:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>ajax</h1>
<form action="" method="post">
{% csrf_token %}
<div>
用户名:<input type="text" name="username" id="username">
</div>
<div>
密码:<input type="password" name="password" id="password">
</div>
<div>
<input type="button" id="btn" value="确认">
{# <input type="submit" id="btn" value="确认">#}
</div>
</form>
<script src="{% static 'jquery.js' %}"></script>
<script>
$('#btn').click(function () {
$.ajax({
url:"{% url 'app03:login' %}", #请求地址
type:'post', #请求类型
data:{ #携带的数据
uname:$('#username').val(),
pwd:$('#password').val(),
#这里需要加上csrf_token的值,不然会forbidden
csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(),
},
success:function (res) {
var res_Str = JSON.parse(res); #将json对象解析成前端的object对象
console.log(res_Str,typeof res_Str);
if(res_Str['code'] === 0){
location.href=res_Str['success'] #前端并没有重定向的方法 需要用location.href指定一个连接 然后去请求我们后端传进来的路径地址
}else if(res_Str['code'] === 1){
location.href=res_Str['fail']
}
}
})
})
</script>
</body>
</html>
三.局部刷新
实际操作中登录失败会提示用户名密码失败,我们上面登录失败会再请求login这个页面,下面实现局部刷新提示一下:
import json
def login(request):
if request.method == 'GET':
return render(request,'manytable/login.html')
else:
uname = request.POST.get('username')
pwd = request.POST.get('paddword')
if uname == 'test' and pwd == '123':
# return redirect('app03:show_book')
ret = {'code':0,'success':'/app03/show_book/'}
return HttpResponse(json.dumps(ret))
else:
# return redirect('app03:login')
ret = {'code':1,'fail':'用户名或密码错误!!'} #只需要改这里就行,提示一句话就行。
return HttpResponse(json.dumps(ret))
前端修改:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>ajax</h1>
<form action="" method="post">
{% csrf_token %}
<div>
用户名:<input type="text" name="username" id="username">
</div>
<div>
密码:<input type="password" name="password" id="password">
</div>
<div>
<input type="button" id="btn" value="确认">
{# <input type="submit" id="btn" value="确认">#}
</div>
<span style="color: red;font-size: 16px" id="error"></span> #增加一个标签,后端传递过来的信息添加到这里来
</form>
<script src="{% static 'jquery.js' %}"></script>
<script>
$('#btn').click(function () {
$.ajax({
url:"{% url 'app03:login' %}",
type:'post',
data:{
uname:$('#username').val(),
pwd:$('#password').val(),
csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(),
},
success:function (res) {
var res_Str = JSON.parse(res);
console.log(res_Str,typeof res_Str);
if(res_Str['code'] === 0){
location.href=res_Str['success']
}else if(res_Str['code'] === 1){
$('span').text(res_Str['fail']) #给span标签设置值
}
}
})
})
</script>
</body>
</html>
结果:
四.csrf_token设置的方法
第一种:
data:{
uname:$('#username').val(),
pwd:$('#password').val(),
csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(),
},
第二种:
data:{
uname:$('#username').val(),
pwd:$('#password').val(),
csrfmiddlewaretoken:{{ csrf_token }}, #模板渲染的方式
},
五.外部引入ajax
单纯写在js文件中:
$('#btn').click(function () {
$.ajax({
url:"/app03/login/",
//url:"{% url '/app03/login' %}", #js不识别模板语法
type:'post',
data:{
uname:$('#username').val(),
pwd:$('#password').val(),
csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(),
//csrfmiddlewaretoken:{{ csrf_token }}, #js不识别模板语法
},
success:function (res) {
var res_Str = JSON.parse(res);
console.log(res_Str,typeof res_Str);
if(res_Str['code'] === 0){
location.href=res_Str['success']
}else if(res_Str['code'] === 1){
$('span').text(res_Str['fail'])
}
}
})
});
引入ajax:
<script src="{% static 'ajax.js' %}"></script>
前端html中也看不到ajax代码了:
外部文件导入的方式来写js代码,那么js代码中不能写django的模板语法,因为html文件的加载顺序:url–视图–html模板渲染 — return给浏览器 – 浏览器渲染 — srcipt的src --才去请求js文件 --那么这个js文件的代码此时才加载到你的html文件中 – 就没有模板渲染的步骤了 – 就没有办法替换对应的模板语法。
视情况而定,如果有大量的模板语法不建议使用外部引入ajax的方法。