AJAX
AJAX是Asynchronous JavaScript And Xml(异步JavaScript和xml) 缩写
它是表示一些技术的混合交互的一个术语,可以使我们获取和显示新的内容而不必载入一个新的web页面。提高用户体验

通信协议
搭建服务器环境
wamp集成环境
-windows 操作系统
-Apache 提供静态资源服务(html页面,js文件,css文件,图片、)
Mysql 数据库
php 变成语言 可以用来开发网站
wamp配置
apache安装配置
安装
安装路径D:\wamp
配置根路径
默认的网站根路径是安装目录的www子目录(D:\wamp\www),如果不想使用默认目录,可以自己配置。配置方式如下:
- 找到文件D:\wamp\bin\apache\Apache2.4.4\conf\httpd.conf 或者打开如下文件(实际是同一个文件)
- 在文件中搜索DocumentRoot,找到239行位置
- 修改根路径为如下形式:(如果要配置虚拟主机,这里配置成根路径;如果不配置根路径,可以配置成D:\ajax;现在配置的是虚拟主机形式;两个位置应该保持一致)
配置虚拟主机
配置虚拟主机可以配置多个网站(域名和网站目录对应),配置步骤如下
- 开启虚拟主机辅配置,在httpd.conf 中找到如下位置,然后把前面的井号去掉

- 配置虚拟主机,打开conf/extra/httpd-vhosts.conf

分别修改以下三项,其它项无需指定。- DocumentRoot "E:/www/example"
- ServerName "example.com "
- ServerAlias "www.example.com"
- 修改DNS(hosts)文件(C:\Windows\System32\drivers\etc\hosts), 添加如下内容:
127.0.0.1 example.com
127.0.0.1 www.example.com - 重启apache
- 访问http://www.example.com或者http://example.com
配置多个虚拟主机的实例如下:
- httpd-vhosts.conf文件配置

- hosts文件配置

网站
页面由一系列页面组成(js,css,图片,html标签,这些所以文件被称为资源)
静态网站
就是提前写好的html页面(包括图片、媒体文件。。。静态资源文件)
存在问题
随着网站规模增大,可维护性逐渐降低
没有交互性
动态网站
动态是指html页面是动态生成的,这里的动态生成的不一定是一个完整的页面,有可能仅仅是页面的一部分,或者仅仅是数据
AJAX原生
以前没ajax的时候,使用的隐藏帧


创建XHR对象
创建XMLHttpRequest()对象
var xhr=new XMLHttpRequest() //标准浏览器
var xhr=new ActiveXObject("Microsoft.XMLHTTP");//IE6
兼容写法
var xhr=null; if(window.XMLHttpRequest){ xhr=new XMLHttpRequest(); }else{ xhr=new ActiveXObject("Microsoft.XMLHTTP") }
请求参数分析
请求参数
参数1 :请求方式 (get获取数据,post提交数据)
参数2:请求地址
参数3:同步或者异步标志位,默认是true表示异步,false表示同步
get,post请求区别
如果get请求,那么请求参数必须在url中传递
例 xhr.open('get','page.php?usname='+uname+'&password='+pw,true);但是在IE下如果有中文传递,IE会显示乱码
兼容IE写法 先把传递值 encode编码 encodeURI()用来对中文参数进行编码,防止乱码
var param='username='+username+'&password='+password;
xhr.open('get','page.php?'+encodeURI(param),true);
如果是post请求,不需要在url传递,也不需要转码,通过send传递,必须设置请求头信息
post请求
设置请求头 内容类型
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") 固定值
发送请求 xhr.send(param) // 这里的var param='username='+username+'&password='+password;
执行发送动作
例 xhr.send() //get请求这里需要添加null参数 xhr.send(null),post是直接填值 xhr.send(值)
指定回调函数
当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
例
xhr.onreadystatechange =function(){ if(xhr.readyState ==4){ if(xhr.status ==200){ alert(xhr.responseText) } } }这里是函数的声明,而不是调用。实际上是浏览器来调用的,调用的时间是根据readyState的值来调用的。
readyState一共有5个值
=0 表示xhr对象创建完成
=1 表示 表示已经发生了请求
=2 浏览器已经收到了服务器响应数据,但数据还没解析
=3 正在解析数据,但还没解析完,不能使用
=4 数据已经解析完成,可以使用 ,但这个数据不一定是正常,需要判断
window.onload=function(){
var btn=document.getElementById("input3"); btn.onclick=function(){ var username=document.getElementById('input1').value; var password=document.getElementById('input2').value; var xhr=new XMLHttpRequest(); console.log(xhr.readyState)//输出0 var param='username='+username+'&password='+password; xhr.open('post','page.php?',true); xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") xhr.send(param); console.log(xhr.readyState)//输出1 xhr.onreadystatechange=function(){ //代码执行到这时,不会一直等待函数,而是会直接执行下面。这就是异步效果,不堵塞 console.log(xhr.readyState)//输出2,3,4调用了三次,调用条件是readyState状态发生了变化(不包括从0到1) if(xhr.readyState == 4){ if(xhr.status == 200){ //这里的200表示数据是正常的 ,http常见状态码 ,200表示响应成功,404没有找到,500服务端错误 alert(xhr.responseText); //响应数据格式,还有一种 xhr.responseXML 现在用的不多 } } } } }
AJAX封装
JS文件 function ajax(url,type,param,callback,datatype) { var xhr=null; if(window.XMLHttpRequest){ xhr=new XMLHttpRequest; }else{ xhr=ActiveXObject("Microsoft.XMLHTTP") }; if(type=="get"){ url+="?"+param; }; xhr.open(type,url,true); var nul=null; if(type="post"){ nul=param; xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") }; xhr.send(nul); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ var data=xhr.responseText; if(datatype=="json"){ data=JSON.parse(data); }; console.log(data); callback(data); } } } }//每个参数需要做严格判断
html文件
<body> <input type="text" id="input" placeholder="admin" /> <span id="info"></span> <script src="ajax.js"></script> <script> var input=document.getElementById("input"); input.onclick=function(){ ajax("page.php","post","username=zhangsan&password=123",function(a) { var info=document.getElementById("info"); info.innerHTML=a.username+a.password; },"json"); 这里调用ajax封装函数 并且传参 } </script>
php文件
<?php $arr=$_POST["username"]; $str=$_POST["password"]; echo '{"username":"' .$arr. '","password":"' .$str. '"}';//这里拼接字符串,分成三个字符串 ?>
这里的封装不完美,只是为了理解封装原理
XMLHttpRequest.responseType
XMLHttpRequest.responseType 属性是一个枚举类型的属性,返回响应数据的类型。它允许我们手动的设置返回数据的类型。如果我们将它设置为一个空字符串,它将使用默认的"text"类型。
在工作环境(Work Environment)中将responseType的值设置为"document"通常会被忽略. 当将responseType设置为一个特定的类型时,你需要确保服务器所返回的类型和你所设置的返回值类型是兼容的。那么如果两者类型不兼容呢?恭喜你,你会发现服务器返回的数据变成了null,即使服务器返回了数据。还有一个要注意的是,给一个同步请求设置responseType会抛出一个InvalidAccessError 的异常。
responseType支持以下几种值:
""responseType为空字符串时,采用默认类型DOMString,与设置为text相同。arraybufferresponse是一个包含二进制数据的 JavaScriptArrayBuffer。blobresponse是一个包含二进制数据的Blob对象 。documentresponse是一个 HTMLDocument或 XMLXMLDocument,这取决于接收到的数据的 MIME 类型。请参阅 XMLHttpRequest 中的 HTML 以了解使用 XHR 获取 HTML 内容的更多信息。jsonresponse是一个 JavaScript 对象。这个对象是通过将接收到的数据类型视为 JSON 解析得到的。textresponse是一个以DOMString对象表示的文本。ms-streamresponse是下载流的一部分;此响应类型仅允许下载请求,并且仅受 Internet Explorer 支持。
jQuery封装
html代码
<body> <input type="text" id="input" placeholder="admin" /> <input type="button" value="titi" id="submit"> <div id="info"></span> <script src="ajax.js"></script> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> var submit=document.getElementById('submit'); submit.onclick=function(){ var datas=document.getElementById('input').value; $.ajax({ type:'post', url:'page.php', data:{abc:datas},//这里的abc是php文件中post或者get获取的键名 dataType:'json',//还支持 xml,json,text,html,script jsonp success:function(data) { var info = document.getElementById('info'); if (data.flag == 0) {//这里的data已经被JSON.parse()处理过了,变成对象了。所以data.flag=0 info.innerHTML = '没有这本书'; } else { var tag = '<ul><li>书名:' + data.bookname + '</li><li>作者:' + data.author + '</li><li>描述:' + data.desc + '</li></ul>'; info.innerHTML = tag; } } }) } </script> </body>
php代码
<?php // $code = $_GET['code']; $codes = $_POST['abc']; $books = array(); $books['sgyy'] = array('bookname'=>'三国演义','author'=>'罗贯中','desc'=>'一个杀伐纷争的年代'); $books['shz'] = array('bookname'=>'水浒传','author'=>'施耐庵','desc'=>'108条好汉的故事'); $books['xyj'] = array('bookname'=>'西游记','author'=>'吴承恩','desc'=>'佛教与道教的斗争'); $books['hlm'] = array('bookname'=>'红楼梦','author'=>'曹雪芹','desc'=>'一个封建王朝的缩影'); // 这里的array_key_exists用来判断数组中没有对应键名 if(array_key_exists($codes,$books) == 1){ $book = $books[$codes];//这里根据参数获取一本书的信息 echo json_encode($book); }else{ echo '{"flag":0}';//这里echo的是json字符串 } // echo $qq; ?>
完全用jquery写 $(function(){ $("#submit").click(function(){ var datas = $("#input").val(); $.ajax({ type:'post', url:'./page.php', data:{abc:datas}, dataType:'json', success:function(data){ if(data.flag == 0){ $("#info").html("该图书不存在"); }else{ var tag = '<ul><li>书名:' + data.bookname + '</li><li>作者:' + data.author + '</li><li>描述:' + data.desc + '</li></ul>'; $("#info").html(tag); } }, error:function(data){ console.dir(data); $("#info").html("服务器发生错误,请与管理员联系");//报错时触发函数 } }); }); });
XML数据格式
xml 开头 <?xml version="1.0" encoding="utf-8" ?>
xml数据格式
元数据 :描述数据的数据
<booklist> <books> <name>三国</name> <author>罗贯中</author> </books> <books> <name>水浒</name> <author>施耐庵</author> </books> </booklist>
现在很少使用这种格式,因为有一定缺陷,元数据标签占据的数据量很大,效率有折扣。而且做数据解析的时候不方便
XML数据解析
常用的
getElementsByTagName()
removeChild() 方法删除指定的节点(或元素)。
createElement() 方法创建新的元素节点。
createTextNode() 方法创建新的文本节点。
appendChild() 方法向节点添加子节点(在最后一个子节点之后)。
如需创建带有文本内容的新元素,需要同时创建元素节点和文本节点。
PHP开发xml
跟html差不多,要设置响应头信息,保证浏览器能识别xml文件类型
header("Content-Type:text/xml;charset=utf-8")
同步异步
页面加载的同步与异步 (白屏与不刷新)
1、普通的页面效果 :w3school.org
2、页面不刷新效果:评论加载
两者之间行为方式
1、同步 彼此等待 ----阻塞
2、异步 各做各的 ----非阻塞


js时间处理机制
js单线程+事件队列
事件队列中任务执行条件
1、主线程已经空闲
2、任务满足触发条件
1、定时函数(延时时间已经到达)
2、事件函数 (特定事件被触发)
3、AJAX的回调函数(服务器端有数据响应)
JavaScript 是单线程执行的,也就是无法同时执行多段代码,当某一段代码正在执行的时候,所有后续的任务都必须等待,形成一个队列,一旦当前任务执行完毕,再从队列中取出下一个任务。这也常被称为 “阻塞式执行”。所以一次鼠标点击,或是计时器到达时间点,或是 Ajax 请求完成触发了回调函数,这些事件处理程序或回调函数都不会立即运行,而是立即排队,一旦线程有空闲就执行。假如当前 JavaScript 进程正在执行一段很耗时的代码,此时发生了一次鼠标点击,那么事件处理程序就被阻塞,用户也无法立即看到反馈,事件处理程序会被放入任务队列,直到前面的代码结束以后才会开始执行。如果代码中设定了一个 setTimeout,那么浏览器便会在合适的时间,将代码插入任务队列,如果这个时间设为 0,就代表立即插入队列,但不是立即执行,仍然要等待前面代码执行完毕。所以 setTimeout 并不能保证执行的时间,是否及时执行取决于 JavaScript 线程是拥挤还是空闲。
个人总结重点
ajax几个函数名。创建xhr对象 var xhr=new XMLHttpRequest IE下 var xhr=new ActiveXObject("Microsoft.XMLHTTP")
兼容IE的写法 设置var xhr=null; 然后用if else 兼容写法
请求参数 xhr.open("get或者post","请问文件url",true);
发送动作 xhr.send();
get,post请求区别 get请求是在url中传参,同时send中填null,兼容IE需要encode转码;post是在send中,不需要转码。需要设置请求头。xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") 固定值
指定回调函数 xhr.onreadystatechange=function(){
if(xhr.onreadyStats==4){//0、xhr对象创建完毕 1、发送了请求 2、浏览器收到服务器响应数据,还没解析 3、正在解析,还没解析完 4、解析完毕。但需要对数据进行判断
if(xhr.status==200){ //对数据进行判断
var data=xhr.responseText 或者xhr.responseXML
}
}
}
php开发XML 需要设置响应头 浏览器才能识别XML类型 header("Content-Type:text/xml;charset=utf-8")
js处理机制,js单线程,回调函数 定时函数 事件函数 进入事件队列 浏览器空闲时执行

浙公网安备 33010602011771号