本节内容:
1、什么是AJAX
2、应运场景
3、AJAX的优缺点
4、基于js 的AJAX技术实现
5、jQueryd的$.ajax
6、跨域请求
一,什么是AJAX
AJAX(Asynchronous Javascript And XML)翻译:我要通过Javascript的技术(语言)利用异步将xml数据作为传输的通道,传输给谁,服务器端。
也是表单提交的一种之前是form 第二种是ajax
前者是光明正大的发送数据,后者是偷摸的发送数据
明着发最大的特点是会刷新页面
ajax是发完以后整个页面不动的(局部刷新)这也是他的特点
另一个特点的异步传送
他不会干扰你做任何其他的事情,你发送完这个请求之后,并不需要在这里阻塞的等待的其他消息(不是必须非得等到服务端把响应发给我)
这也是AJAX的两个特点、局部刷新,异步传输。
总体下来就是,前端给后端发送数据,后端处理完了,再返回给前端的一个数据
为什么前端给后端发送数据,因为前端的页面是给用户看的,所有的数据都是基于用户的选择,用户输入的数据都是先给的前端,前端拿到之后,才发给后端处理
二、AJAX的应运场景
当我们在百度中输入一个“老”字后,会马上出现一个下拉列表!列表中显示的是包含“老”字的4个关键字。(服务端会搜集这段时间访问,最多的关键字 ,出现在下列)
其实这里就使用了AJAX技术!当文件框发生了输入变化时,浏览器会使用AJAX技术向服务器发送一个请求,查询包含“老”字的前10个关键字,然后服务器会把查询到的结果响应给浏览器,最后浏览器把这4个关键字显示在下拉列表中。
- 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
- 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为zhangSan的用户是否存在,最终服务器返回true表示名为lemontree7777777的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。
- 整个过程中页面没有刷新,只是局部刷新了;
- 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;
三,AJAX的优缺点
优点:
- AJAX使用Javascript技术向服务器发送异步请求;
- AJAX无须刷新整个页面;
- 因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高;
缺点:
- AJAX虽然提高了用户体验,但无形中向服务器发送的请求次数增多了,导致服务器压力增大;
- 因为AJAX是在浏览器中使用Javascript技术完成的,所以还需要处理浏览器兼容性问题;
四、基于js 的AJAX技术实现(四步操作)
1、创建核心对象 XMLHttpRequest
这里面最最要的一件事情是,我们要围绕着一个核心对象,去展开(对象名字叫什么都行)这个对象是通过哪个类创建的呢?叫XMLHttpRequest
XMLHttp = XMLHttpRequest()
实例化一个对象 拿到这个对象就是我们的核心对象
有了这个对象以后我们要向服务端发送数据,要发送数据我们就要和服务端建立链接
注意,各个浏览器对XMLHttpRequest的支持也是不同的!为了处理浏览器兼容问题,给出下面方法来创建XMLHttpRequest对象:
function createXMLHttpRequest() {
var xmlHttp;
// 适用于大多数浏览器,以及IE7和IE更高版本
try{
xmlHttp = new XMLHttpRequest();
} catch (e) {
// 适用于IE6
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
// 适用于IE5.5,以及IE更早版本
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){}
}
}
return xmlHttp;
}
2,链接
是通过一个函数open完成的。open谁来调用呢?就是你上面创建的那个对象XMLHttp.open("里面写请求路径,请求方式")
链接好之后要发送数据了
3、发送请求
发送数据有自己的一个方法send,也是XMLHttp这个对象调用XMLHttp.send("name = wangkuan")发什么内容就写在里面比如name = wangkuan但是记住一点这个send里面放的内容是请求体的内容
(HTTP协议有一个请求头,请求体,响应头,响应体,基于这种协议去操作,我送这个请求按照这种请求头,请求体来,你的服务端就知道了,你服务端发响应头,响应体,我按照你的这种绑定方式我也可以解析开,大家一个交互的协议,
请求头:就是一些相关属性的设定
请求体:一些相关的内容,get没有请求体,因为你get访问的数据都在url后面,所以他不需要有请求体)
如果是get请求,他就没有内容,这个send 里面就直接发送,因为你 的内容在URL后面,里面就什么也别填直接send(),建议写成send(null)因为有的浏览器不认识,好像是火狐,因为是get请求没有请求体,所以只能发送空
以上三步完成顺利的化,数据已近到了服务端了,服务端已近到了jango那步了,到了jango的那里了,视图函数后面括号里的那个参数里面(request)然后服务端要返回给我一堆内容,比如字符串,客户端得把这个字符串取到,取到在做什么事情就是客户端的事情了,这次交呼叫结束了,那我们第四步要做什么?
监听服务端把数据处理好了(把你发送过去的数据做了一堆处理,比如验证什么的,处理完了给一个响应,告诉你,你的数据通过没通过,有没有问题,或返回一些其他数据,怎么接受这个数据呢,我们做个监听,监听的意思就是我得知道服务器那边处理完了,我这边要接受,通过readyState的状态监听,最重要的就是把数据拿到手通过responseText,进行处理)
4、监听
什么意思呢,就是我现在要通过一个监听函数(某个事件不发生,这个函数永远不执行,一但某事件发生了,他会触发这个函数执行),现在要写一个监听函数,这个函数监听的,我的这个XMLHttp对象的一个属性叫readyState是一个值,1 2 3 4,一个状态,什么状态呢,现在服务端在处理数据,从他发送数据到他处理数据,到这个数据回来之后,我这边就可以读数据了,读他的数据到读完了的过程一共分为四步,我们需要知道的就是第四步,因为第四步意味着,数据已近返回到我的前端这来了,我们仅仅做一个接收就OK了。接收用什么接收 还是这个对象XMLHttp,用它的一个属性responseText 到第四步时候数据发到服务端了,我这变就做监听,
第一步你到没到数据库,
第二步到了数据库回来没回来,
第三步,回来了我开始读,
第四步,读,读完了,
读完之后我就可以做操作了,如果前端已近把数据读完了,接下来我可以把这个数据取出来,然后再把这些数据取出来做一些处理,随便用一个变量去接收他abc=XMLHttp.responseText 那abc就是服务器端给的数据了
整个过程我给后台发数据,后台再给我返回数据,通过这四步来实现, 第四步监听里面又分四步
XMLHttpRequest对象有一个onreadystatechange事件,它会在XMLHttpRequest对象的状态发生变化时被调用
onreadystatechange事件会在状态为1、2、3、4时引发。
下面代码会被执行四次!对应XMLHttpRequest的四种状态!
xmlHttp.onreadystatechange = function() {
alert(\'hello\');
};
但通常我们只关心最后一种状态,即读取服务器响应结束时,客户端才会做出改变。我们可以通过XMLHttpRequest对象的readyState属性来得到XMLHttpRequest对象的状态。
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4) {
alert(\'hello\');
}
};
其实我们还要关心服务器响应的状态码是否为200,其服务器响应为404,或500,那么就表示请求失败了。我们可以通过XMLHttpRequest对象的status属性得到服务器的状态码。
最后,我们还需要获取到服务器响应的内容,可以通过XMLHttpRequest对象的responseText得到服务器响应内容。
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
alert(xmlHttp.responseText);
}
};
第四步
整个过程
一,两个URL 第一个是返回一个前端页面,第二个是提交之后返回的 写成两个了
二 视图函数
三,返回这个页面
四、点击提交触发一个函数 ,func1,这个函数里面就是以上的四个部分 创建核心对象, 链接 发送 监听 第四步是写在 第二步的open链接上面的
简单的一个GET方式ajax提交完成,点击提交按钮,页面是不会刷新的
发送POST请求:
<1>需要设置请求头:xmlHttp.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);
注意 :form表单会默认这个键值对;不设定,Web服务器会忽略请求体的内容。
服务端接收
结果
创建XMLHttpRequest对象;
调用open()方法打开与服务器的连接;
调用send()方法发送请求;
为XMLHttpRequest对象指定onreadystatechange事件函数,这个函数会在
XMLHttpRequest的1、2、3、4,四种状态时被调用;
XMLHttpRequest对象的5种状态,通常我们只关心4状态。
XMLHttpRequest对象的status属性表示服务器状态码,它只有在readyState为4时才
能获取到。
XMLHttpRequest对象的responseText属性表示服务器响应内容,它只有在
readyState为4时才能获取到!
五、jQueryd的$.ajax
$.ajax的两种写法:
$.ajax("url",{})
$.ajax({})
//第二种是常用的
$.ajax的基本使用
$.ajax({
url:"//",
data:{a:1,b:2},
type:"GET",
success:function(){}
})
最后一个是可以设置回调函数,执行完后,执行的函数
复制代码 ----------请求数据相关: data, processData, contentType, traditional-------------- data: 当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式 (urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。 # function testData() { # $.ajax("/test",{ //此时的data是一个json形式的对象 # data:{ # a:1, # b:2 # } # }); //?a=1&b=2 processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false, # 那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString() # ,最后得到一个[object,Object]形式的结果。 # {"1":"111","2":"222","3":"333"}.toString();//[object Object] # 该属性的意义在于,当data是一个dom结构或者xml数据时,我们希望数据不要进行处理,直接发过去, # 就可以讲其设为true。 contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。 # 用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据, # 比如contentType:"application/json",即向服务器发送一个json字符串: # $.ajax("/ajax_get",{ # # data:JSON.stringify({ # a:22, # b:33 # }), # contentType:"application/json", # type:"POST", # # }); //{a: 22, b: 33} # 注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象 traditional:一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]}, traditional为false会对数据进行深层次迭代;
dataType:预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。
# 默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;比如我们的服务器响应的
# content Type为json格式,这时ajax方法就会对响应的内容进行一个json格式的转换,if转换成功,我们在
# success的回调函数里就会得到一个json格式的对象;转换失败就会触发error这个回调函数。如果我们明确地指
# 定目标类型,就可以使用data Type。
# dataType的可用值:html|xml|json|text|script
# 见下dataType实例
dataFilter: 类型:Function 给 Ajax返回的原始数据的进行预处理的函数。见下dataFilter实例
提交
视图函数
也可以直接写json格式的比如\' "hello" \' 第一个引号是给HttpResponse 的,因为HttpResponse返回的必须是一个字符串
$.ajax(\'/user/allusers\', {
成功执行这个
success: function (data) {
console.log(arguments);
},
失败执行这个
error: function (jqXHR, textStatus, err) {
// jqXHR: jQuery增强的xhr
// textStatus: 请求完成状态
// err: 底层通过throw抛出的异常对象,值与错误类型有关
console.log(arguments);
},
不管成功失败都执行
complete: function (jqXHR, textStatus) {
// jqXHR: jQuery增强的xhr
// textStatus: 请求完成状态 success | error
console.log(\'statusCode: %d, statusText: %s\', jqXHR.status, jqXHR.statusText);
console.log(\'textStatus: %s\', textStatus);
},
根据状态码执行函数
statusCode: {
\'403\': function (jqXHR, textStatus, err) {
console.log(arguments); //注意:后端模拟errror方式:HttpResponse.status_code=500
},
\'400\': function () {
}
}
});
六、跨域请求
同源策略:http协议,IP地址,端口 也就是,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。
跨域:浏览器的同源策略,导致我们不能跨域请求去取数据,数据发过去了,接收了,浏览器不给你看,浏览器阻碍这条数据给你,浏览器做的这件事情。
场景:比如两家公司合作,肯定是不同的网站,可是我想让你把我的数据拿过去引用,那你得给我一个接口,但是有同源策略,给你阻碍住了,你还是取不到。
怎么才能够在有同源策略的情况下,我也进行跨域请求数据,sjax不能跨域请求数据了。
但是可以通过<script src = " "></script> src这个标签可以实现 img的src也可以
JSONP是JSON with Padding的略称。可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
JSONP就像是JSON+Padding一样(Padding这里我们理解为填充)
jsonp原理:动态的在head里面加上,script标签,然后再把它去掉,由于浏览器有同源策略,所以默认发跨域请求是发不过去的。如果我们想要自己开发一个能够远程发送跨域请求的话,那我们就可以依赖于jsonp来做,那jsonp又是什么呢?他不是一个技术,而是一种策略,这个策略就是一个小机智,怎么小机智呢,由于script块的src不受同源策略,我可以动态的生成一个src快的标签,给他加上src属性,那他就可以去访问了,访问成功后,返回一个字符串回来,但是对于script的块来说的话,你返回的字符串,我可以在浏览器上,用编译成JavajQuery的代码,如果他们调用函数的代码,我恰巧在内部定义了一个函数,那他就会自动调用我的函数。
#---------------------------http://127.0.0.1:8001/login def login(request): print(\'hello ajax\') return render(request,\'index.html\') #---------------------------返回用户的index.html <h1>发送JSONP数据</h1> <script> function fun1(arg){ alert("hello"+arg) } </script> <script src="http://127.0.0.1:8002/get_byjsonp/"></script> //返回:<script>fun1("kuan")</script> #-----------------------------http://127.0.0.1:8002/get_byjsonp def get_byjsonp(req): print(\'8002...\') return HttpResponse(\'fun1("kuan")\')
https://files.cnblogs.com/files/wupeiqi/ajax_demo.zip
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="button" onclick="AjaxRequest()" value="跨域Ajax" /> <div id="container"></div> <script src="jquery-1.8.2.min.js" type="text/javascript"></script> <script type="text/javascript"> function AjaxRequest() { $.ajax({ url: \'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403\', type: \'GET\', dataType: \'jsonp\', jsonp: \'callback\', jsonpCallback: \'list\', success: function (data) { $.each(data.data,function(i){ var item = data.data[i]; var str = "<p>"+ item.week +"</p>"; $(\'#container\').append(str); $.each(item.list,function(j){ var temp = "<a href=\'" + item.list[j].link +"\'>" + item.list[j].name +" </a><br/>"; $(\'#container\').append(temp); }); $(\'#container\').append("<hr/>"); }) } }); } </script> </body> </html>
其实就是我这边,返回一个他那边已近定义好的函数,里面的参数我已近写好了,这个函数一定是前端定义好的,我直接把你想执行的函数放里面
后端
kkk就是想传的内容,把他填充到了前端已近定义好的内容,这就是一个填充
这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。
最简单的方式$ajax
<script type="text/javascript" src="/static/jquery-2.2.3.js"></script> <script type="text/javascript"> $.ajax({ url:"http://127.0.0.1:8002/get_byjsonp", dataType:"jsonp", //必须有,告诉server,这次访问要的是一个jsonp的结果。 jsonp: \'callbacks\', //jQuery帮助随机生成的:callbacks="wner" success:function(data){ alert(data) } }); </script> #-------------------------------------http://127.0.0.1:8002/get_byjsonp def get_byjsonp(req): callbacks=req.GET.get(\'callbacks\') print(callbacks) #wner return HttpResponse("%s(\'yuan\')"%callbacks)
jsonp: \'callbacks\'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名\'SayHi\',server端接受callback键对应值后就可以在其中填充数据打包返回了;
jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。
利用jQuery可以很方便的实现JSONP来进行跨域访问。
此外,如果说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现
<script type="text/javascript" src="/static/jquery-2.2.3.js"></script> <script type="text/javascript"> $.ajax({ url:"http://127.0.0.1:8002/get_byjsonp", dataType:"jsonp", jsonp: \'callbacks\', jsonpCallback:"SayHi" //他两发送过去就是"callbacks":"SayHi" }); function SayHi(arg){ alert(arg); } </script> #--------------------------------- http://127.0.0.1:8002/get_byjsonp def get_byjsonp(req): callback=req.GET.get(\'callbacks\') print(callback) return HttpResponse(\'%s("kuan")\'%callback)