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