AJAX基础
一、什么是AJAX
Asynchronous Javascript And Xml
异步的 JS 和 Xml (JSON)
异步访问:
当客户端向服务器端发送请求时,服务器在处理的过程中,客户端无需等待,可以做其他操作
AJAX的优点:
1.异步 的 访问方式
2.局部 的 刷新方式
使用场合:
1.搜索建议
2.表单验证
3.前后端完全分离
SPA -> Single Page Application
二、AJAX核心对象-异步对象(XMLHttpRequest)
1.什么XMLHttpRequest
简称为 "xhr"
称为 "异步对象",代替浏览器向服务器发送异步的请求并接受响应
2.创建异步对象
xhr的创建是由js来提供的
主流的异步对象是XMLHttpRequest类型的,并且主流浏览器都支持(IE7+,Chrome,Firefox,Safari,Opera)
支持XMLHttpRequest:
通过 new XMLHttpRequest()
不支持XMLHttpRequet:
通过new ActiveXObject("Microsoft.XMLHTTP")
创建一个判断浏览器是否支持性的JS文件:
//file:common.js function createXhr(){ var xhr = null; //根据不同的浏览器创建不同的异步对象 if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); } return xhr; }
创建xhr
#urls.py url(r'^createxhr$', views.create_view), #---------------------- #views.py def create_view(request): return render(request, 'createxhr.html')
//creatxhr.html <!DOCTYPE html> <html lang="en"> <head> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <button onclick="createXhr()">创建XHR</button> </body> </html>
三、XHR的成员
1.方法 - open()
作用:创建请求
语法:xhr.open(method,url,async);
method:请求方式,取值 'get' 或 'post'
url:请求地址,取值 字符串
async:是否采用异步的方式发送请求
true:异步的
false:同步的
示例:使用get方式向02-server的地址发送异步请求
xhr.open('get',路由地址',true);
2.属性 - readyState
作用:表示请求状态,通过不同的请求状态值来表示xhr与服务器的交互情况
由0-4共5个值来表示5个不同的状态
- 0:请求尚未初始化
- 1:已经与服务器建立连接
- 2:服务器端已经接收请求信息
- 3:服务器端处理中...
- 4:响应完成
3.属性 - status
作用:表示服务器端的响应状态码
- 200 : 服务器端正确处理请求并给出响应
- 404 : Not Found
- 500 : Internal Server Error
示例:
if(xhr.readyState==4 && xhr.status==200){
//可以接收服务器端的响应信息
}
4.属性 - responseText
作用:表示服务器端响应回来的数据
if(xhr.readyState==4 && xhr.status==200){
//可以接收服务器端的响应信息
console.log(xhr.responseText);
}
5.事件 - onreadystatechange
作用:每当xhr的readyState值发生改变时要触发的操作 - 回调函数
xhr.onreadystatechange = function(){
if(xhr.readyState==4 && xhr.status==200){
//可以接收服务器端的响应信息
console.log(xhr.responseText);
}
}
6.方法 - send()
作用:通知xhr向服务器端开始发送请求
语法:xhr.send(body);
body:请求主体
get请求:
body的值为null
xhr.send(null);
post请求:
body的置为 具体的请求数据
xhr.send("请求数据");
四、AJAX的操作步骤
(一)GET请求
1.创建 xhr
2.创建请求 - open()
3.设置回调函数 - onreadystatechange
1.判断状态
2.接收响应
3.业务处理
4.发送请求 - send(null)
(1)演示使用ajax发送get请求的步骤
#演示使用ajax发送get请求的步骤 url(r'^ajax-get$', views.ajax_get_view), url(r'^server-ajax-get$', views.server_ajax_get),
def ajax_get_view(request): return render(request, 'ajax-get.html') def server_ajax_get(request): return HttpResponse('这是server的响应内容')
//file:ajax-get.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/static/common.js"></script> <script> function btnShow(){ //1.创建xhr var xhr = createXhr(); //2.创建请求 xhr.open("get","/demo/server-ajax-get",true); //3.设置回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState==4 && xhr.status==200){ //接收服务器端响应的数据 var res = xhr.responseText; document.getElementById("show").innerHTML = res; } } //4.发送请求 xhr.send(null); } </script> </head> <body> <button onclick="btnShow()">显示</button> <a href="/demo/server-ajax">显示</a> <div id="show"></div> </body>
(2)演示使用ajax发送get请求并附带参数
# 演示使用ajax发送get请求并附带参数 url(r'^ajax-get-params$', views.ajax_get_params), url(r'^server-ajax-get-params$', views.server_ajax_get_params),
def ajax_get_params(request): return render(request, 'ajax-get-params.html') def server_ajax_get_params(request): # 1.接收前端传递过来的两个参数 name = request.GET['name'] age = request.GET['age'] # 2.相应数据给前端 s = '姓名:%s,年龄:%s' % (name, age) return HttpResponse(s)
//file:ajax-get-params.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/static/common.js"></script> <script> function btnShow(){ //1.创建xhr var xhr = createXhr(); //2.创建请求(带参数) var url = "/demo/server-ajax-get-params?name=maplefox&age=30"; xhr.open("get",url,true); //3.设置回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState==4&&xhr.status==200){ document.getElementById("show").innerHTML = xhr.responseText; } } //4.发送请求 xhr.send(null); } </script> </head> <body> <button onclick="btnShow()">显示</button> <div id="show"></div> </body> </html>
(二)POST请求
1.创建xhr
2.创建请求
1.请求方式改为post
2.有请求参数的话不能拼在地址的后面
3.设置回调函数
4.设置请求消息头 - Content-Type
xhr.setRequestHeader(
"Content-Type",
"application/x-www-form-urlencoded"
)
5.发送请求
请求数据放在send()的参数位置处
示例:xhr.send("name=wang&age=30&gender=男");
演示使用ajax发送post请求的步骤
#使用AJAX发送post请求 url(r'^ajax-post/$', views.ajax_post_view), #简单版 不同步数据库 url(r'^server-ajax-post/$', views.server_ajax_post_view),
def ajax_post_view(request): return render(request, 'ajax-post.html', locals()) def server_ajax_post_view(request): uname = request.POST['uname'] upwd = request.POST['upwd'] msg = "账号:" + uname + "密码" + upwd return HttpResponse(msg)
//file:ajax-post.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/static/common.js"></script> <script src="/static/jquery-1.11.3.js"></script> <script> $(function(){ //为 #btnPost 绑定 click 事件 $("#btnPost").click(function(){ //1.创建xhr var xhr = createXhr(); //2.创建请求 xhr.open("post","/demo/server-ajax-post/",true); //3.设置回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState==4 && xhr.status == 200){ alert(xhr.responseText); } } //4.设置请求消息头 xhr.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" ); //5.发送请求 var uname = $("#uname").val(); var upwd = $("#upwd").val(); // 获取csrfmiddlewaretoken的值 var csrf = $("[name='csrfmiddlewaretoken']").val(); var params = "uname="+uname+"&upwd="+upwd+"&csrfmiddlewaretoken="+csrf; xhr.send(params); }); }); </script> </head> <body> {% csrf_token %} <p> 用户名称 <input type="text" id="uname"> </p> <p> 用户密码 <input type="password" id="upwd"> </p> <p> <input type="button" id="btnPost" value="提交"> </p> </body> </html>
(三)使用AJAX完成注册操作
(1)get请求检查用户是否存在
# 使用 AJAX 完成注册操作 url(r'^register/$', views.register_view), # 检查用户是否存在 url(r'^checkuname/$', views.checkuname_view),
# ====使用ajax完成注册操作==== from .models import Users def register_view(request): return render(request, 'register.html') # ====检查用户是否存在==== def checkuname_view(request): # 1.接收前端传递过来的参数 uname uname = request.GET['uname'] # 2.判断uname在User数据库中是否存在 user = Users.objects.filter(uname=uname) # 3.根据查询到的结果给出响应 if user: return HttpResponse('1') return HttpResponse('0')
//file:register.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/static/common.js"></script> <script src="/static/jquery-1.11.3.js"></script> <script> $(function(){ //为 #uname 绑定 blur 事件 $("#uname").blur(function(){ //1.创建xhr var xhr = createXhr(); //2.创建请求 - /demo/checkuname var uname = $("#uname").val(); var url = "/demo/checkuname?uname="+uname; xhr.open("get",url,true); //3.设置回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState==4 && xhr.status==200){ //$("#uname-tip").html(xhr.responseText); if(xhr.responseText == "1"){ $("#uname-tip").html("用户名称已经存在"); }else{ $("#uname-tip").html("通过"); } } } //4.发送请求 xhr.send(null); }); }); </script> </head> <body> <div> <p> 用户名称:<input type="text" id="uname"> <span id="uname-tip"></span> </p> <p> 用户密码:<input type="password" id="upwd"> </p> <p> 电子邮箱:<input type="email" id="uemail"> </p> <p> 用户昵称: <input type="text" id="nickname"> </p> <p> <input type="button" value="注册"> </p> </div> </body> </html>
(2)get请求完成注册操作(添加用户)
# 使用 AJAX 完成注册操作 url(r'^get-register/$', views.get_register_view), # 检查用户是否存在 url(r'^checkuname/$', views.checkuname_view), # 通过get请求注册操作增加新用户(同步数据库) url(r'^server-get-register-user/$', views.server_get_register_user_view),
from .models import Users # ====通过get请求 注册增加新用户=== def get_register_view(request): return render(request, 'register.html') # ====检查用户是否存在==== def checkuname_view(request): # 1.接收前端传递过来的参数 uname uname = request.GET['uname'] # 2.判断uname在User数据库中是否存在 user = Users.objects.filter(uname=uname) # 3.根据查询到的结果给出响应 if user: return HttpResponse('1') return HttpResponse('0') # ====通过get请求方式注册增加新用户==== def server_get_register_user_view(request): # 1.接收前端传递的数据 uname = request.GET['uname'] upwd = request.GET['upwd'] uemail = request.GET['uemail'] nickname = request.GET['nickname'] # 2.通过数据实现增加操作(通过异常处理,处理增加失败的问题) try: Users.objects.create(uname=uname, upwd=upwd, uemail=uemail, nickname=nickname) return HttpResponse('1') except Exception as e: print(e) return HttpResponse('0')
//file:get-register.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/static/common.js"></script> <script src="/static/jquery-1.11.3.js"></script> <script> /** * 检查用户名称是否存在的函数 * 需要一个返回值ret * 返回true,则表示用户名称已存在 * 返回false,则表示用户名称不存在 */ function checkuname(){ var ret = false; //1.创建xhr var xhr = createXhr(); //2.创建请求 - /demo/checkuname var uname = $("#uname").val(); var url = "/demo/checkuname?uname="+uname; xhr.open("get",url,true); //3.设置回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState==4 && xhr.status==200){ //$("#uname-tip").html(xhr.responseText); if(xhr.responseText == "1"){ $("#uname-tip").html("用户名称已经存在"); ret = true; }else{ $("#uname-tip").html("通过"); } } } //4.发送请求 xhr.send(null); return ret; } $(function(){ //为 #uname 绑定 blur 事件 $("#uname").blur(function(){ checkuname(); }); //为#btnReg绑定click事件实现注册 $("#btnReg").click(function(){ //1.创建xhr var xhr = createXhr(); //2.创建请求 var uname = $("#uname").val(); var upwd = $("#upwd").val(); var uemail = $("#uemail").val(); var nickname = $("#nickname").val(); var url = "/demo/server-get-register-user?uname="+uname+"&upwd="+upwd+"&uemail="+uemail+"&nickname="+nickname; console.log(url); xhr.open("get",url,true); //3.设置回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState==4 && xhr.status==200){ if(xhr.responseText == "1"){ alert("注册成功"); }else{ alert("注册失败"); } } } //4.发送请求 xhr.send(null); }); }); </script> </head> <body> <div> <p> 用户名称:<input type="text" id="uname"> <span id="uname-tip"></span> </p> <p> 用户密码:<input type="password" id="upwd"> </p> <p> 电子邮箱:<input type="email" id="uemail"> </p> <p> 用户昵称: <input type="text" id="nickname"> </p> <p> <input type="button" value="注册" id="btnReg"> </p> </div> </body> </html>
(3)post请求完成注册操作(添加用户)
# 使用 AJAX 完成注册操作 url(r'^post-register/$', views.post_register_view), # 检查用户是否存在 url(r'^checkuname/$', views.checkuname_view), # 通过post请求注册操作增加新用户(同步数据库) url(r'^server-post-register-user', views.server_post_register_user_view),
from .models import Users # ====通过post请求 注册增加新用户=== def post_register_view(request): return render(request, 'post-register.html') # ====检查用户是否存在==== def checkuname_view(request): # 1.接收前端传递过来的参数 uname uname = request.GET['uname'] # 2.判断uname在User数据库中是否存在 user = Users.objects.filter(uname=uname) # 3.根据查询到的结果给出响应 if user: return HttpResponse('1') return HttpResponse('0') # ====通过post请求方式注册增加新用户==== def server_post_register_user_view(request): # 1.接收前端传递的数据 uname = request.GET['uname'] upwd = request.GET['upwd'] uemail = request.GET['uemail'] nickname = request.GET['nickname'] # 2.通过数据实现增加操作(通过异常处理,处理增加失败的问题) try: Users.objects.create(uname=uname, upwd=upwd, uemail=uemail, nickname=nickname) return HttpResponse('1') except Exception as e: print(e) return HttpResponse('0')
//file:post-register.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/static/common.js"></script> <script src="/static/jquery-1.11.3.js"></script> <script> /** * 检查用户名称是否存在的函数 * 需要一个返回值 * 返回true,则表示用户名称已存在 * 返回false,则表示用户名称不存在 */ function checkuname(){ var ret = false; //1.创建xhr var xhr = createXhr(); //2.创建请求 - /demo/checkuname var uname = $("#uname").val(); var url = "/demo/checkuname?uname="+uname; xhr.open("get",url,false); //3.设置回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState==4 && xhr.status==200){ //$("#uname-tip").html(xhr.responseText); if(xhr.responseText == "1"){ $("#uname-tip").html("用户名称已经存在"); ret = true; }else{ $("#uname-tip").html("通过"); } } } //4.发送请求 xhr.send(null); return ret; } $(function(){ //为 #uname 绑定 blur 事件 $("#uname").blur(function(){ checkuname(); }); //为#btnRegPost绑定click事件 $("#btnRegPost").click(function(){ //调用checkuname()并接收返回值, //如果返回true则给出用户名存在的提示, //如果返回false,则正常发送数据到服务器端执行注册的操作 if(checkuname()){ alert("用户名称已存在,请更新"); }else{ //1.创建xhr var xhr = createXhr(); //2.创建请求 xhr.open("post","/demo/server-post-register-user/",true); //3.设置回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState==4 && xhr.status==200){ if(xhr.responseText == "1"){ alert("注册成功"); }else{ alert("注册失败"); } } } //4.设置请求消息头 xhr.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" ); //5.发送请求 - 参数 var uname = $("#uname").val(); var upwd = $("#upwd").val(); var uemail = $("#uemail").val(); var nickname = $("#nickname").val(); var csrf = $("[name='csrfmiddlewaretoken']").val(); var params = "uname="+uname+"&upwd="+upwd+"&uemail="+uemail+"&nickname="+nickname+"&csrfmiddlewaretoken="+csrf; xhr.send(params); } }); }); </script> </head> <body> {% csrf_token %} <div> <p> 用户名称:<input type="text" id="uname"> <span id="uname-tip"></span> </p> <p> 用户密码:<input type="password" id="upwd"> </p> <p> 电子邮箱:<input type="email" id="uemail"> </p> <p> 用户昵称: <input type="text" id="nickname"> </p> <p> <input type="button" value="注册" id="btnRegPost"> </p> </div> </body> </html>
(4)使用get请求显示用户列表(使用ajax读取数据)
# 使用get请求显示用户列表(使用ajax读取数据) url(r'^show-users/$', views.show_users), url(r'^server-show-users/$', views.server_show_users),
# ====显示用户列表(使用ajax读取数)==== def show_users(request): return render(request, 'show-users.html') def server_show_users(request): users = Users.objects.all() msg = '' for user in users: msg += "%s_%s_%s_%s_%s|" % (user.id, user.uname, user.upwd, user.uemail, user.nickname) msg = msg[0:-1] return HttpResponse(msg)
//file:show-user.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/static/common.js"></script> <script src="/static/jquery-1.11.3.js"></script> <script> $(function(){ $("#btnShow").click(function(){ var xhr = createXhr(); xhr.open("get","/demo/server-show-users",true); xhr.onreadystatechange = function(){ if(xhr.readyState==4 && xhr.status==200){ var msg = xhr.responseText; var html = ""; var users = msg.split("|"); for(var i=0;i<users.length;i++){ html += "<tr>"; //将每个人的信息通过 _ 再一次拆分 var infos = users[i].split('_'); html += "<th>"+infos[0]+"</th>"; html += "<th>"+infos[1]+"</th>"; html += "<th>"+infos[2]+"</th>"; html += "<th>"+infos[3]+"</th>"; html += "<th>"+infos[4]+"</th>"; html += "</tr>"; } $("#content").html(html); } } xhr.send(null); }); }); </script> </head> <body> <button id="btnShow">显示</button> <table width="500" border="1"> <thead> <tr> <th>ID</th> <th>用户名</th> <th>密码</th> <th>邮箱</th> <th>昵称</th> </tr> </thead> <tbody id="content"></tbody> </table> </body> </html>