Ajax
概念
Ajax,即异步的JavaScript和XML(Asynchronous JavaScript and XML),是一种无需重新加载整个网页的情况下,更新部分网页的技术
优点
- 通过异步模式,提升用户体验
- 优化浏览器和服务器间传输,减少不必要的数据往返以及带宽占用
- 在客户端运行时,承担了一部分服务器承担的工作,减少了大用户量下的服务器负载
缺点
- 不支持浏览器的回退(back)按钮
- 会暴露和服务器交流的细节,存在安全问题
- 对搜索引擎支持较弱
使用步骤
一般包括三步
- 创建XMLHttpRequest对象(异步调用对象)
- 创建新的HTTP请求,指定该HTTP请求的方法、URL
- 设置响应HTTP请求状态变化的函数
需要注意的是,Ajax需要与服务器通信,因此需要用服务器启动,而不是直接在浏览器中打开页面
这里使用Wampserver64来访问,下载地址(提取码:gixc)和使用说明(提取码:u3lw)见链接
创建XMLHttpRequest对象
XMLHttpRequest是Ajax的核心,一种支持异步请求的技术
可以向服务器提出请求并处理响应,不阻塞用户,在页面加载后进行页面的局部更新
这一对象因为在不同浏览器中支持方式不同,所以需要考虑兼容性
1 //Ajax第一步,创建XMLHttpRequest对象 2 //封装通用的xhr,兼容各个版本 3 function createXHR(){ 4 //判断浏览器是否将XMLHttpRequest作为本地对象实现,针对firefox、opera等 5 if(typeof XMLHttpRequest != 'undefined'){ 6 return new XMLHttpRequest(); 7 } 8 else if(typeof ActiveXObject != 'undefined'){ 9 //将所有可能出现的ActiveXObject版本放在一个数组里 10 var xhrArr = ['Microsoft.XMLHTTP','MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP.2.0']; 11 //遍历创建XMLHttpRequest对象 12 var len = xhrArr.length; 13 var xhr; 14 for(var i=0;i<len;i++){ 15 try{ 16 //创建XMLHttpRequest对象 17 xhr = new ActiveXObject(xhrArr[i]); 18 //遇到支持的版本号就退出 19 break; 20 } 21 //如果当前循环的版本号不支持,捕获错误但是没有操作 22 catch(ex){ 23 24 } 25 } 26 return xhr; 27 } 28 else{ 29 throw new Error('No XHR object available!'); 30 } 31 }
也可以不用考虑过多的版本号,直接分IE和非IE来创建XMLHttpRequest
1 var xmlhttp; 2 if(window.XMLHttpRequest){ 3 //针对IE7+、Firefox、Chrome、Opera、Safari 4 xmlhttp = new XMLHttpRequest(); 5 } 6 else{ 7 //针对IE6、IE5 8 xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); 9 }
创建HTTP请求
用XMLHttpRequest对象的open方法来创建(注意是创建而不是发送)
该方法初始化请求,准备发送同一个域中使用相同协议和端口的URL发送请求,否则会因为安全原因报错
其中包括三个参数
请求类型
分get和post两种
get速度快,大部分情况下都可使用
post在以下三种情况下是get无法替代的:
- 无法使用缓存文件(更新服务器上文件/数据库时)
- 向服务器发送大量数据(post方法没有发送的数据量限制)
- 发送包含未知字符的用户输入
URL
文件在服务器上位置,open方法中唯一必须传入的参数
这里的文件可以为任何类型的/服务器脚本文件
async
一个布尔值,默认为true(异步),也可设置false(同步)
设置状态请求变化函数
用函数监测XMLHttpRequest的readystatechange属性变化情况
其中readyState属性值为4时,表示异步响应内容解析完成,可以在客户端调用
status属性值在[200,300)时,表示异步调用(交易)成功
status属性值为304时,表示请求资源没有被修改,可以用浏览器缓存(即之前用过异步相同内容而且成功了,该内容在缓存中)
1 //响应XMLHttpRequest对象状态变化的函数 2 //onreadystatechange在readystatechange属性变化时触发 3 xhr.onreadystatechange = function(){ 4 //异步响应内容解析完成,可以在客户端调用 5 if(xhr.readyState === 4){ 6 //异步调用(交易)成功,或者请求资源没有被修改,可以用浏览器缓存(即之前用过异步而且成功了) 7 if((xhr.status >=200 && xhr.status<300) || xhr.status === 304){ 8 //返回服务器数据 9 } 10 } 11 }
发送请求
用send方法向服务器发送请求
其中当创建请求(open方法)的请求方法为post时,才可传入字符串/对象,否则值只可传入null
在post前,需要先用setRequestHeader方法添加HTTP头(固定写法,如下),然后才能发送数据
1 xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
获取服务器端返回的数据
在收到响应后,XMLHttpRequest的四个属性会被填充,可以从responseText/responseXML来获得从服务器进程返回的数据
其中responseText是字符串形式(使用较多),responseXML是DOM兼容的文档数据对象
渲染数据
获取服务器端返回的数据后,可以把该数据添加到当前HTML中
添加的方法包括DOM操作、字符串拼接等
JSON
概念
即JavaScript对象表示法(JavaScript object notation),一种数据交换的文本格式,并不是编程语言
语法规则
JSON可以支持JavaScript中的基本类型、数组、对象
基本类型中,字符串必须用双引号表示,数值必须用十进制表示,不能用NaN和Infinity,不支持undefined
对象中,键名必须放在双引号中,对象的末尾没有分号,且同一个对象中不可出现两个同名属性
数组/对象中最后一个成员后不可加逗号
方法
parse()
把JSON字符串转化成对象
语法为JSON.parse(JSON字符串)
JavaScript中的eval方法与其类似,但是也可以执行不符合JSON格式的代码,因此尽可能少用
stringify()
把一个值转成符合JSON格式的字符串,并可以被JSON.parse()方法还原
语法为JSON.stringify(原生JavaScript值)
Jquery的Ajax方法
主要使用的是$.ajax()方法
内部包括五个参数:请求地址、请求方式、同步异步、数据格式以及请求成功的回调
1 $.ajax({ 2 url:"./server/slider.json", 3 type:"post", 4 async:true, 5 dataType:"json", 6 success:function(imgData){ 7 jQurenderDataToDom(imgData); 8 //这一步是请求成功之后的渲染数据的函数 9 } 10 })
跨域
定义
从一个域名网页请求另一个域名资源,也就是只要协议、域名、端口三者其一有不同,就是跨域
其中域名、协议、端口均相同时,被称作同源
解决方法
跨域资源共享(CORS)、JSONP(常用)、修改document.domain、使用window.name
JSONP
即填充式JSON(JSON with padding),一种跨域解决方案
JSONP包括回调函数(响应到来时页面中调用的函数,由用户提供)和数据(传入回调函数中的JSON数据,由服务器返回)
JSONP是利用了在页面上可以引入不同域上的js脚本文件来实现的
1 //封装JSONP 2 function getJSONP(url,callback){ 3 if(!url){ 4 return; 5 } 6 //声明数组用来随机生成函数名 7 var a = ['a','b','c','d','e','f','g','h','i','j'], 8 r1 = Math.floor(Math.random()*a.length), 9 r2 = Math.floor(Math.random()*a.length), 10 r3 = Math.floor(Math.random()*a.length), 11 name = 'getJSONP'+a[r1]+a[r2]+a[r3],//这里不用getJSONP打头也可以 12 cbname = 'getJSONP.'+name;//这里是将来服务端传回的getJSONP的属性值,必须以getJSONP打头 13 //判断url中是否含有? 14 if(url.indexOf('?') === -1){ 15 url += '?jsonp=' + cbname; 16 } 17 else{//在url地址的?参数后面再加一个新参数,因此用&隔开 18 url += '&jsonp' + cbname; 19 } 20 //动态创建script标签 21 var script = document.createElement('script'); 22 //定义被脚本文件执行的回调函数(最核心部分) 23 getJSONP[name] = function(data){ 24 try{ 25 callback && callback(); 26 } 27 catch(e){ 28 } 29 finally{ 30 //无论是否执行成功,删除getJSONP的属性以及回调函数,以释放内存空间 31 delete getJSONP[name]; 32 script.parentNode.removeChild(script); 33 } 34 } 35 //定义script的src,把这个新的script添加到head标签的最后 36 script.src = url; 37 document.getElementsByTagName('head')[0].appendChild(script); 38 }