Ajax
AJAX - 阿贾克斯
1、什么是AJAX
AJAX:Asynchronous Javascript And Xml(异步JS和Xml)
同步访问:
当客户端向服务器发送请求时,服务器在处理过程中,浏览器只能等待
缺点:整个网页会刷新
异步访问:
当客户端向服务器发送请求时,服务器在处理过程中,浏览器可以做其他的事情,不需要一直等待,效率较高
优点:局部刷新
使用场合:
1、搜索建议
2、表单验证
3、前后端完全分离
2、AJAX核心对象 异步对象 - XMLHttpRequest
1、什么是XMLHttpRequest
主要称为‘异步对象’,代替浏览器向服务器发送请求并接收响应
该对象主要由JS来提供
2、创建异步对象
主流的异步对象是XMLHttpRequest类型的,并且主流的浏览器(IE7+,Chrom,FireFox,Safari,Oper)已经全部支持该对象。低版本浏览器(IE7,IE6)是无法使用XMLHttpRequest,需要使用ActiveXObject来创建异步对象
判断浏览器是否支持XMLHttpRequest
if(window.XMLHttpRequest){
//如果浏览器支持XMLHttpRequest的话,window.XMLHttpRequest则是一个非undefined的值,
//如果浏览器不支持的话,此处就是一个undefined
var xhr = new XMLHttpRquest();
}else{
//浏览器不支持XMLHttpRequest
var xhr = new ActiveXobject("Microsoft.XMLHTTP");
}
function createXhr(){ if(window.XMLHttpRequest){ return new XMLHttpRequest(); }else { return new ActiveXObject('Microsoft.XMLHTTP'); } }
<button onclick="getXhr()">创建XHR</button> <script src="/static/js/common.js"></script> <script> function getXhr(){ console.log(createXhr()) } </script>
<button onclick="getXhr()">创建XHR</button> <script> function getXhr(){ //判断浏览器是否支持xhr console.log(window.XMLHttpRequest) if(window.XMLHttpRequest){ var xhr = new XMLHttpRequest(); console.log(xhr); }else{ var xhr = new ActiveXObject('Microsoft.XMLHTTP'); } } </script>
3、xhr的成员
1、方法 - open()
作用:创建/打开请求
语法:xhr.open(method,url,asyn)
method:指定请求的方式,取值为‘get’或‘post’
url:请求地址,字符串
asyn:指定是否使用异步的方式发送请求
true:使用异步
false:使用同步
示例:
//1、获取xhr对象
var xhr = createXhr();
//2、创建请求
xhr.open('get','/01_server',true);
2、属性 - readyState
作用:请求的状态,通过不同的请求状态来表示xhr与服务器的交互情况
由0-4共5个值表示5个不同的状态
0:请求尚未初始化
1:已经与服务器建立连接
2:服务器端已经接收请求
3:请求正在处理中
4:响应已经完成
3、属性 - status
作用:表示的是服务器端的响应状态码
200:表示服务器正确处理所有的请求并给出响应
403:请求被拒绝
404:请求资源未找到
500:服务器内部错误
4、属性 - responseText
作用:服务器端响应回来的文本
5、事件 - onreadystatechange
作用:每当readyState的值发生改变时要触发的操作 - 回调函数
在此函数中,要判断当readyState的值为4并且status的值为200的时候,才可以正常的接收响应数据(responseText)
6、方法 - send()
作用:发送请求
语法:xhr.send(body)
body:表示请求主体,get请求的话,此处为null,post请求的话,此处为要提交的数据
4、使用AJAX发送get请求
1、步骤
1、创建xhr对象
2、创建请求 - open()
3、设置回调函数 - onreadystatechange
4、发送请求 - send()
<body> <button onclick='btnClick()'>点我试试!!!!</button> <div id="show"></div> <script src="/static/js/common.js"></script> <script> function btnClick(){ //1、创建/获取xhr var xhr = createXhr(); //2、创建请求 - open() xhr.open('get','/02_server/',true); //3、设置回调函数 - onreadystatechange xhr.onreadystatechange = function(){ //当xhr.readyState的值为4,xhr.Status的值为200时,才可以接收xhr if(xhr.readyState ==4 && xhr.status==200){ var resText = xhr.responseText; document.getElementById("show").innerHTML=resText; } } //4、发送请求 -send() xhr.send(null) } </script>
2、发送带参数的get请求
在请求地址中追加参数即可
xhr.open('get','/02_server/?uname=sf.zh',true);
<body> <input id="input" type="text"> <button id="send" >发送</button> <div id="show"></div> <script src="/static/js/common.js"></script> <script src="/static/js/jquery-1.11.3.js"></script> <script> $(function(){ $('#send').click(function(){ var name = $('input').val(); xhr = createXhr(); xhr.open('get','/03_server/?uname='+name,true); xhr.onreadystatechange=function(){ if(xhr.readyState==4 && xhr.status==200){ var resText = xhr.responseText; $('#show').html(resText) } } xhr.send() }); }); </script> </body>
5、使用AJAX发送post请求
1、步骤
1、创建/获取xhr
2、创建请求 - open()
3、设置回调函数 - onreadystatechange
4、发送请求 - send()
xhr.send('uname=sf.zh&upwd=123456');
2、csrf验证
必须手动提交csrfmiddlewaretoken的值到服务器,否则无法通过csrf的验证,服务器会返回403
解决方案1:
1、在模板中,通过JS获取cookies中csrftoken的值
var csrf = $.cookie('csrftoken')
2、将获取出来的值,拼成参数,再发送给服务器
解决方案2:
1、在模板中,通过一个隐藏域获取cookies中csrftoken的值
<input type='hidden' name='csrfmiddlewaretoken' value='fvNkJBG2sJRXBpZKMNHYpUFygzMLUvnQ1iH>
var csrf = $('[name=csrfmiddlewaretoken]').val();
2、将获取出来的值,拼成参数,在发送给服务器
</head> <body> <script src="/static/js/common.js"></script> <script src="/static/js/jquery-1.11.3.js"></script> <script> $(function(){ $("#btnPost").click(function(){ //1、创建xhr var xhr = createXhr() //2、创建请求 xhr.open('post','/06_server/',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 csrf = $('[name=csrfmiddlewaretoken]').val();//属性选择器 var params = 'uname='+uname+"&csrfmiddlewaretoken="+csrf xhr.send(params) }) }) </script> <div> {% csrf_token %} <p> 用户名: <input type="text" id="uname"> </p> <button id="btnPost">POST请求</button> </div> </body> </html>
3、必须设置一个请求消息头 - Content-Type
xhr.setRequsetHeader('Content-Type','application/x-www-form-urlencoded');
注意:该操作要在xhr.send()之前增加
Content-Type:application/x-www-form-urlencoded:表示任何数据都可提交
Content-Type:text/plain;charset=UTF-8:表示只有英文和数字可以提交
<body> <div> <p> 姓名:<input type="text" id="uname"> </p> <p> 密码:<input type="password" id="upwd"> </p> <p> <input type="button" id="btnPost" value="POST"> </p> </div> <p id="show"></p> <form> <!-- 为了向cookie中增加csrftoken值,可以写在任何位置,可以不写在form表单中,--> {% csrf_token %} </form> <script src="/static/js/common.js"></script> <script src="/static/js/jquery-1.11.3.js"></script> <script src="/static/js/jquery.cookie.js"></script> <script> $(function(){ $('#btnPost').click(function(){ //1、获取xhr var xhr = createXhr(); //2、创建请求 xhr.open('post','/04_server/',true); //3、设置回调函数 xhr.onreadystatechange = function () { if(xhr.readyState==4 && xhr.status==200){ $('#show').html(xhr.responseText); } } //设置请求头 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded') //4、发送请求 //从cookie中获取scrftoken的值 var csrf = $.cookie('csrftoken') var uname = $("#uname").val(); var upwd = $('#upwd').val(); var params = "uname="+uname+"&upwd="+upwd+"&csrfmiddlewaretoken="+csrf; xhr.send(params) }) }) </script> </body>
JSON
1、JSON的介绍
JSON:JavaScript Object Notation(表现形式)
将复杂的数据按照JS对象的格式进行响应
2、JSON表现
1、JSON可以表示单个对象
1、使用{}表示单个对象
2、在{}中,使用key:value的形式来表示数据(属性和值)
3、key必须使用双引号引起来(单引号有时不好用)
4、value如果是字符串的话,也必须使用双引号引起来,是数字的话可以引也可以不引
var obj = {
"name":"xdl",
"age": 20,
"gender":"男",
}
取值:
obj.name
obj.age
obj.gender
2、json可以表示一个数组
1、使用[]表示一个数组
2、在数组中允许包含若干普通数据 或 json对象
1、使用json数组表示普通数据
var arr = ["xdl","gj"]
2、使用json数组表示若干对象
var arr = [
{
"name":"xdl",
"age": 20,
"gender":"男",
},
{
"name":"gj",
"age": 18,
"gender":"女",
},
]
3、取值
方法1:
$(arr).each(function(i,obj){
console.log(i+":"+obj.name);
})
方法2:
$.each(arr,function (i,obj){
console.log(i+":"+obj.name);
})
3、后台处理json
1、前后台json数据交互流程(后→前)
1、后台先获取数据
类型:
1、元祖
2、列表
3、字典
4、QuerySet
2、在后台将数据转换为符合json格式的字符串
3、在后台将json格式的字符串响应给前端
return HttpResponse(json格式字串)
4、在前端,将响应回来的json串解析成json对象
2、Python(Django)中的json处理
1、元祖,列表,字典
使用Python提供的json模块就可以完成转换
import json
json.dumps(元祖|列表|字典)
2、Django中的查询结果集 - QuerySet
使用Django提供的序列化类 完成QuerySet到json字符串的转换
from django.core import serializers
jsonStr = serializers.serialize("json",QuerySet)
def server09_views(request): user = User.objects.all() jsonStr = serializers.serialize('json',user) return HttpResponse(jsonStr)
在Js中通过JSON.parse()得到的结果
[
{
"model": "index.user",
"pk": 1, #主键
"fields": #除了主键之外的所有字段
{
"uname": "xdl",
"upwd": "123456",
"uphone": "123456789",
"uemail": "aaa@163.com"
}
}
]
3、django中查询单个对象
使用Entry.objects.get(条件)查询单条数据,是不允许被序列化为json格式的
1、方案1
使用Entry.objects.filter()来替换Entry.objects.get(),替换后则可以正常使用serializers
2、方案2
将Entry.objects.get()得到的单个对象转换成字典后再使用json.dumps()
class User(models.Mode):
name = models.CharField(maxlength=30)
pwd = models.CharField(maxlengtj=30)
def to_dict(self):
dic = {
'name':self.name,
'pwd':self.pwd
}
return dic
user = User.objects.get(id=1)
jsonStr = json.dumps(user.to_dict())
3、前端处理json
将后端响应回来的json字符串转换成json对象
在JS中:
var json对象 = JSON.parse(json字符串)
jQuery AJAX
在jquery中提供了对原生ajax的封装操作
1、$obj.load(),该方法发送的是GET方法
作用:异步加载数据到$obj元素中
语法:$obj.load(url,data,callback)
1、url:异步请求的地址
2、data:传递给服务器端的数据(可选)
1、可以传递普通的字符串
“name=xdl&age=20”
2、可以传递json
{
"name":"xdl",
"age":20
}
3、callback:异步请求完成后的回调函数(可选)
function(resText,statusText){
resText:响应数据
statusText:响应的状态文本,比如200代表的状态文本就是success
}
<body> <button id="btnload">发送load</button> <div id="show"> </div> <script src="/static/js/jquery-1.11.3.js"></script> <script> $(function(){ $('#btnload').click(function () { var params = "uname=xdl&uage=20"; $('#show').load('/09_server/',params,function (resText,statusText) { //resText:响应数据(可选):姓名:xdl,年龄:20 console.log(resText); //statusText:响应的状态文本(可选):success console.log(statusText); var arr = JSON.parse(resText); $.each(arr,function(i,obj){ console.log(obj.pk)//主键为1 console.log(obj.fields.uname)//名字为xdl }) }) }) }) </script> </body>
2、$.get(),发送的是GET请求
语法:$.get(url,data,callback,type)
1、url:异步请求的地址
2、data:请求提交的参数(可选)
3、callback:请求成功时的回调函数(可选)
function(data){
data:表示的是响应回来的的数据
}
4、type:指定返回内容的格式类型(可选)
1、html:响应回来的内容是html文本
2、text:响应回来的内容是text文本
3、json:响应回来的内容是json对象
<body> <button id="btnGet"> jquery ajax get</button> <div id="show"></div> <script src="/static/js/jquery-1.11.3.js"></script> <script> $(function(){ var params = { 'name':'xdl', 'age':20, } $("#btnGet").click(function(){ $.get('/10_server/',params,function(data){ //$("#show").html(data); var html=""; $.each(data,function(i,obj){ html+="<p>"; html+="<b>"+obj.name+"</b>"; html+="<b>"+obj.age+"</>"; html+="</p>" }); $("#show").html(html) },'json'); }); }); </script> </body>
3、$.post(),发送的是POST请求
语法:$.get(url,data,callback,type)
参数同$.get()
注意:该方法需要csrf验证
var data = {
"csrfmiddlewaretoken":$.cookie('csrftoken')
}
<body> <button id="btnPost">jq ajax Post </button> <script src="../js/jquery-1.11.3.js"></script>//静态文件加载方式 <script src="../js/jquery.cookie.js"></script> <script> $(function () { $('#btnPost').click(function () { var params = { "csrfmiddlewaretoken":$.cookie('csrftoken') } $.post('/11_server/',params,function (data) { alert(data) }) }) }) </script> </body>
4、$.ajax()
特点:所有的操作都可以自己定制
语法:$.ajax({json对象})
json对象:
1、url:字符串,要异步请求的地址
2、type:字符串,提交方式,get 或 post
3、data:json对象或字符串,要传递到后台服务器的参数,参数名不需要加引号,值需要加引号
data :{
uphone:‘123456’,
csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()
},
4、dataType:字符串,指定响应回来的数据的类型
1、'html':响应回来的数据是html文本
2、'text':响应回来的数据是text文本
3、'script':响应回来的数据是JavaScript代码
4、'json':响应回来的数据是json对象
5、'xml':响应回来的数据是xml文档
6、'jsonp':jsonp格式,跨域时使用,(在本网站访问其他网站就是跨域)
5、success:请求和响应成功时的回调函数
success:function(data,textStatus){
data:响应数据
textStatus:响应状态文本
}
6、error:请求和响应出错时的回调函数
error:function(xhr,textStatus){
xhr:异步请求对象
textStatus:响应状态文本
}
7、async:指定是否异步方式
true:使用异步方式
false:使用同步方式
默认为true
<body> 选择省份: <select name="" id="selPro"></select> <select name="" id="selCity"></select> <script src="/static/js/jquery-1.11.3.js"></script> <script> function loadPro(){ $.ajax({ url:'/12_server/', type:'get', dataType:'json', async:false, success:function(data){ var html=""; $.each(data,function (i,obj) { html+="<option value="+ obj.pk +">"; html+=obj.fields.name; html+="</option>"; }); $('#selPro').html(html) ; } }); } function loadCity(id){ $.ajax({ url:'/13_server/', type:'get', data:"id="+id, dataType:'json', success:function(data,testStatus){ console.log(testStatus);//success var html=""; $.each(data,function (i,obj) { html+="<option value="+ obj.pk +">"; html+=obj.fields.name; html+="</option>"; }); $('#selCity').html(html) ; }, }); } $(function () { loadPro(); //初始话就要显示城市信息,但需需要loadPro()返回为同步请求 loadCity($("#selPro").val()) $("#selPro").change(function(){ loadCity($(this).val()); }) }) </script> </body>
def server12_views(request): proList = Province.objects.all() jsonStr = serializers.serialize('json',proList) return HttpResponse(jsonStr) def server13_views(request): id = request.GET['id'] province = Province.objects.get(id=id) #反向查询 cityList = province.city_set.all() jsonStr = serializers.serialize('json',cityList) return HttpResponse(jsonStr)