ajax 不重新加载整个网页的情况下,更新部分网页的技术
注意:ajax只有在服务器上运行才能生效,我在本地一般用PHPstudy
优点:
1、优化用户体验
2、承担了一部分本该服务器端的工作,减轻了服务器端的压力
3、优化了服务器端和浏览器端的传输,减少了带宽占用
缺点:
1、不支持回退按钮
3、安全问题,暴露了与服务器端交互的细节
XMLHttpRequest 对象
1、可以向服务器端发起请求并处理响应,而不阻塞用户
2、可以在不更新整个网页的的情况下,更新部分内容
如何使用ajax
1、创建XMLHttpRequest 对象
2、创建一个HTTP请求,并指定方式、URL(必填)
3、设置响应HTTP请求状态变化的函数
4、发起请求
创建XMLHttpRequest 对象的两种方式:(兼容各浏览器)
1、完整版
//@H_403_64@封装兼容各浏览器的xhr对象 function@H_403_64@ createXhr(){ @H_403_64@IE7+,其他浏览器 @H_403_64@if(@H_403_64@typeof XMLHttpRequest!="undefined"@H_403_64@){ @H_403_64@return @H_403_64@new XMLHttpRequest();@H_403_64@返回xhr对象的实例 }@H_403_64@else @H_403_64@typeof ActiveXObject!="undefined"@H_403_64@IE7及以下 @H_403_64@所有可能出现的ActiveXObject版本 @H_403_64@var arr=["Microsoft.XMLHTTP","MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP.2.0"@H_403_64@]; @H_403_64@var@H_403_64@ xhr; @H_403_64@循环 @H_403_64@for(@H_403_64@var i=0,len=arr.length;i<len;i++@H_403_64@){ @H_403_64@try@H_403_64@{ xhr=@H_403_64@new ActiveXObject(arr[i]);@H_403_64@任意一个版本支持,即可退出循环 @H_403_64@break@H_403_64@; }@H_403_64@catch@H_403_64@(e){ } } @H_403_64@return xhr;@H_403_64@返回创建的ActiveXObject对象 }@H_403_64@else@H_403_64@{ @H_403_64@都不支持 @H_403_64@throw @H_403_64@new Error("您的浏览器不支持XHR对象!"@H_403_64@); } }
2、简略版
@H_403_64@if@H_403_64@(window.XMLHttpRequest){ @H_403_64@new@H_403_64@ XMLHttpRequest(); }@H_403_64@IE7以下 @H_403_64@new ActiveXObject("Microsoft.XMLHTTP"@H_403_64@); } }
测试是否创建成功
.open(method,url,async) 初始化请求并准备发送(只能对同一个域中使用相同端口和协议的URL发送请求)
method :get 或者 post( get 更快更简单,但不能发送大量数据,无法使用缓存文件,而且没有 post 稳定和可靠)
url :必填(文件在服务器上的位置,可以是任何类型,如.txt .xml .asp .PHP)
async:是否异步,true 异步,false 同步(同步时,服务器处理完成之间浏览器必须等待;异步时,服务器未处理完成前,浏览器可以进行其他操作)
get 准备请求直接加上参数,post 准备请求不在此加参数
@H_403_64@2、get创建请求 xhr.open("get","./server/slider.json?user=cyy&age=25",@H_403_64@true@H_403_64@); @H_403_64@post创建请求 xhr.open("post","./server/slider.json",1)">true);
响应XMLHttpRequest 对象状态变化的函数
.onreadystatechange 检测状态变化的函数
.readyState==4 响应内容解析完成
.status>=2==&&.status<300 异步调用成功
.status==304 请求资源没有被修改,可以使用浏览器的缓存
发送请求.send()
发送post请求需要传入参数(以对象形式),发送get请求不需要,可以传入null
post请求需要添加HTTP头
.setRequestHeader("Content-type","application/x-www-form-urlencoded")
@H_403_64@get发送请求 xhr.send(@H_403_64@null@H_403_64@); @H_403_64@post发送请求 xhr.send({user:"cyy",age:25@H_403_64@}); @H_403_64@设置post请求头 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
获取到服务器返回的数据
responseText 服务器返回的数据的字符串形式
responseXML 服务器返回的数据的兼容DOM的文档数据对象(XML形式)
status 返回的状态码(如404表示没找到,200表示已就绪)
status Text 状态码的字符串信息
查看network状态
json 数据格式
全称是javascript对象表示法,目的是为了取代笨重的XML格式
json 可以表示以下三种类型的值:
1、简单值
与js语法相同,可以是字符串、数值、布尔值、null,但不支持undefined
字符串必须用双引号表示,不能用单引号
数值必须是十进制,不能是 NaN 和 Infinity
2、对象
键名必须放在双引号中
同一个对象不应该出现两个同名属性
3、数组
数组或者对象最后一个成员,后面不能加逗号
示例:slider.json
@H_403_64@{ "code": 0@H_403_64@,"slider"@H_403_64@: [ { "linkUrl": "http://www.baidu.com"403_64@ },{ "linkUrl": "http://www.baidu.com"403_64@ } ] }
.responseText 返回的数据是字符串,因此需要先转为对象
使用.eval() 函数
@H_403_64@获取服务器端返回的数据 console.log(@H_403_64@typeof xhr.responseText);@H_403_64@string @H_403_64@把字符串转为对象 console.log(eval("("+xhr.responseText+")"));
eval("("+xhr.responseText+")"); 的意思是强制转化成json对象,之所以写成 eval“("("+data+")");这种格式,原因是由于json是以”{}”的方式来开始以及结束的。在JavaScript中,它会被当成一个语句块来处理,所以必须强制性的将它转换成一种表达式,加上圆括号的目的是迫使eval函数在处理JavaScript代码的时候强制将括号内的表达式转化为对象,而不是作为语句来执行,举一个例子,例如对象字面量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始和结束标记,那么{}将会被认为是执行了一句空语句,所以下面两个执行结果是不同的:
还有 json 对象的两个方法:
1、 JSON.parse() 用于将json字符串转为对象
2、JSON.stringify 将一个值转为JSON字符串
由于eval() 可以执行不符合json格式的代码,有可能会包含恶意代码,所以不推荐使用,建议还是使用.parse()
data=@H_403_64@JSON.parse(xhr.responseText); console.log(data.slider);
最后一步,渲染数据到页面中
放出文件index.html
@H_403_64@<!DOCTYPE html@H_403_64@> @H_403_64@<html lang@H_403_64@="en"@H_403_64@head@H_403_64@> @H_403_64@Meta charset@H_403_64@="UTF-8"@H_403_64@title@H_403_64@>demo@H_403_64@</style@H_403_64@> *{margin:0;padding} .wrapwidth250pxheight50px autooverflowhidden .banner1000px .banner adisplay blockfloat left .banner a img} @H_403_64@script src@H_403_64@="jquery.js"@H_403_64@></script@H_403_64@> @H_403_64@body@H_403_64@div class@H_403_64@="wrap"@H_403_64@> @H_403_64@="banner" id@H_403_64@="banner"@H_403_64@div@H_403_64@> //封装兼容各浏览器的xhr对象 function createXhr(){ IE7+,其他浏览器 if(typeof XMLHttpRequest!="undefined){ return new XMLHttpRequest();返回xhr对象的实例 }else ActiveXObjectIE7及以下 所有可能出现的ActiveXObject版本 var arr=[Microsoft.XMLHTTPMSXML2.XMLHTTP.6.0MSXML2.XMLHTTP.5.0MSXML2.XMLHTTP.4.0MSXML2.XMLHTTP.3.0MSXML2.XMLHTTP.2.0]; xhr; 循环 for iarr.length;i<len;i++){ try{ xhr ActiveXObject(arr[i]);任意一个版本支持,即可退出循环 break; }catch(e){ } } return xhr;返回创建的ActiveXObject对象 else{ 都不支持 throw Error(您的浏览器不支持XHR对象!); } } 1、创建XMLHttpRequest对象 xhrcreateXhr(),data; 响应XMLHttpRequest状态变化的函数 onreadystatechange监测状态变化 xhr.onreadystatechange(){ (xhr.readyState==4){响应内容解析完成 ((xhr.status>=200&&xhr.status300)||304xhr.status>=200&&xhr.status<300 表示交易成功 xhr.status==304 表示缓存后未发生改变,因此可以从缓存中读取 获取服务器端返回的数据 console.log(typeof xhr.responseText);//string 把字符串转为对象 dataJSON.parse(xhr.responseText); console.log(data.slider); 渲染数据 renderData(); } } } 2、get创建请求 xhr.open(get./server/slider.json?user=cyy&age=25true); get发送请求 xhr.send(null); post创建请求 xhr.open("post",true); post发送请求 xhr.send({user:"cyy",age:25}); 设置post请求头 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 渲染数据 renderData(){ imgsdata.slider,str""; bannerdocument.getElementById(banner); imgs.length;iconsole.log(imgs[i]); str+=<a href='+imgs[i].linkUrl'><img src='imgs[i].picUrl'></a>; } console.log(str); banner.innerHTMLstr; } @H_403_64@html@H_403_64@>
jquery的ajax方法:
$.ajax()
$.get()
$.post()
$.getJson()
@H_403_64@jquery的$.ajax() @H_403_64@ $.ajax({ url:"./server/slider.json",1)">请求地址 type:"post",1)">请求方式,默认是get async:@H_403_64@true,1)">异步同步,默认是true异步 dataType:"json",1)">返回的数据格式 success:@H_403_64@function(data){ @H_403_64@响应成功的操作 JQRenderData(data.slider); @H_403_64@data是返回的数据 @H_403_64@ } }); @H_403_64@ JQRenderData(data){ @H_403_64@var str=""@H_403_64@; $.each(data,@H_403_64@(index,obj){ str+="<a href='"+obj.linkUrl+"'><img src='"+obj.picUrl+"'></a>"@H_403_64@; }); $("#banner2"@H_403_64@).html(str); }
$.each( obj,function(index,value){ } ) 方法,遍历对象或数组
index 数组索引或者对象属性名
value 数组项或者对象属性值
以下是用javascript 和 jqeury 两种方式实现的代码
@H_403_64@> @H_403_64@="banner2"@H_403_64@jquery的$.ajax() $.ajax({ url:./server/slider.json请求地址 type:post请求方式,默认是get async:异步同步,默认是true异步 dataType:json返回的数据格式 success:(data){ 响应成功的操作 JQRenderData(data.slider); data是返回的数据 } }); JQRenderData(data){ strobj.linkUrlobj.picUrl; }); $(#banner2).html(str); } @H_403_64@>
什么是跨域:
同源策略:域名、协议、端口都相同
不符合同源策略的请求,就是跨域
跨域常用的解决方式:JSONP
JSONP :JSON with padding (填充式json)
JSONP的原理:
直接用XMLHttpRequest 访问不同域上的数据是不可以的,但是可以在页面上引入不同域的 js 脚本(如 src 或者 href )
@H_403_64@/* 封装JSONP 浏览器端给服务器端发送请求: http://www.baidu.com?jsonp=abc 服务器端响应请求: abc(json数据) */ myJSONP(url,callback){ !url) 如果没有url,则停止 用数组存储10个字母 abcdefghij],i1Math.floor(Math.random()*arr.length),1)">随机生成索引 i2mydataarr[i1]arr[i2]arr[i3];随机生成的请求函数名(属性名) cbnamemyJSONP.name;必须是函数名.请求函数名 跨域url处理 将请求函数名作为最后一个参数传递 (url.indexOf(?===-1原来没有参数 url?jsonp=cbname;参数名可自定义(此处是jsonp) 原来有参数 &jsonp=cbname; } console.log(url); 动态创建script标签 scriptdocument.createElement(script定义被脚本执行的回调函数 myJSONP[name](data){ { callback callback(data);如果有回调,则执行回调 }(e){ 报错时 finally{ 由于每次请求都会生成函数和script标签,长此以往会污染函数 因此每次结束时都要删除函数及变量 delete myJSONP[name]; script.parentNode.removeChild(script); } } script.srcurl; document.getElementsByTagName(head)[].appendChild(script); } 发送跨域请求 myJSONP(http://class.imooc.com/api/jsonp(data){ console.log(data); }); @H_403_64@>
页面返回的数据
url演示