0x00:什么是Ajax?javascript
Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操做HTTP和web服务器进行数据交换(用户不知道也感受不出来,就跟桌面应用程序似的进行数据交互),它不会致使页面从新加载,这样才有更好的用户体验。php
Ajax是基于如下开放标准:css
通俗的说就是使用了javascript(DOM)的XMLHttpRequest对象(ajax核心API也是浏览器的http API)及后续一系列的操做(发送和接收操做),接收来自服务器xml(json)等数据格式的数据,用html和css来显示出来。因此它们只是组合出来的一种新的技术。html
历史什么的我就不介绍了。java
0x01:怎样使用Ajax?web
001:实例化一个XMLHttpRequest对象ajax
var xhr = new XMLHttpReques();chrome
就是这么简单。通常不用考虑兼容性,若是你想让每一用户都能享受到ajax带来的福利。你还要考虑咱们IE5,6的朋友(如今应该用的很少了吧,具体我也不知道);json
你能够定义一个实例化这个对象的函数:跨域
function createXHR() { if(window.XMLHttpRequest) { return new XMLHttpRequest(); } else if(window.ActiveXObject) { return new ActiveXObject(Microsoft.XMLHTTP); } }
这就兼容一切浏览器了。
002:发送请求
实例化对象后,就要发送请求了,要使用XMLHttpRequest对象的open()和send()方法及可选setRequestHeader()方法(请求头设置)。
首先来讲open()方法。它能够接受三个参数,第一个参数是要发送的请求的类型(即GET,POST等),第二个参数是请求的URL(网址)(即服务器上文件的地址,但不能跨域请求),第三个参数是一个布尔值(true表示异步,false表示同步)。
细节:
the first argument:第一个参数GET,POST等是不区分大小写的,可是通用的作法是都用大写。
那何时用GET,何时用POST呢?
GET简单说就是向服务器请求查询资源时用,请求不对服务器有任何反作用,是幂等的(即对同一url屡次请求应该返回相同的结果)
具体如下是GET请求的特色,你能够根据这些特色来使用
1.GET请求的响应能够被浏览器缓存
2.GET请求有长度限制(具体跟浏览器和服务器自身设置有关通常能够2k-8k)
3.GET请求能够在历史记录中查看,(若是发送了敏感数据,别人经过查看你的历史记录就能看见)
4.GET请求能够保存为书签
5.GET请求只有请求头,没有主体,要设置查询字符串参数,首先要进行编码,而后把数据放在url后面,用?把地址和查询参数隔开,
查询参数之间用&隔开例如:www.123.com/aa.php?name=‘wy’l&id=001;url地址栏因此也不能发送敏感数据,用户能看见了。
POST是向服务器发送要处理的数据时用
具体如下是POST请求的特色。
1.通常不对请求的数据的长度进行限制
2.浏览器不进行缓存文件、数据,没法使用缓存文件等
3.数据在主体中,相对GET安全点,通常用户看不见,要是用工具那就另说了,get可能形成CSRF攻击
4.发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
根据这些特色你就知道该何时用GET和POST。
the second argument:第二个参数,须要注意的是,不能进行跨域请求。什么是跨域呢,就是当两个url中只要
其中一项不一样就是跨域,协议,域名,端口不一样就是跨域,具体以下截图,看懂就明白了。
截图来自:http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html
the third argument:第三个参数是能够省略的,那就默认异步(true),异步和同步在不一样的地方解释会有不一样,这里是的意思是,同步的话会阻塞javascript的执行,就是说在调用send()方法后,浏览器就会在这个地方中止后面的代码执行,一直到服务器响应,才再往下执行后面的代码,若是用异步的话,javascript就会在调用了send()方法后,不会等待服务器的响应,继续执行下面的代码,可是你也不能无论了吧,这里就会说到下面要讲的要进行事件监听,当你服务器有响应了,我再去操做你的数据等操做。
说了半天也没有说代码是怎么样的:
//GET请求 xhr.open("GET","www.123.com/bb.php") xhr.open("GET","www.123.com/bb.php?a=2&b=3")//若是你要加上查询数据的话 //POST请求 xhr.open("POST","www.123.com/aa.php")
在说send()方法以前还要说,请求头的设置,若是是GET请求,这一步能够没有,可是要是POST表单编码请求必须要设置“Content-Type”头来指定请求的主题的MIME类型(就是告诉服务器我给的是什么类型的数据)值为:application/x-www-form-urlencoded。它的值还有值能够是application/json,text/plain,text/html,text/xml等,有时候XMLHttpRequest对象会自动识别你发送数据的类型,因此你也能够没有,可是最好设置上。其余的若是你有特殊须要你就设置;有一些头是你不能本身设置,如Content-Length,Date,Referer,User-Agent等,除了这些你均可以本身设置,不须要的浏览器就发送本身默认的请求头。若是对相同的头调用setRequestHeader()屡次,新值不会取代以前的值,而是HTTP请求头包含这个头的多个副本或者这个头将指定多个值。
设置请求头用setRequestHeader()方法。必定要注意了,必须在调用open()方法以后,而且在调用send()方法以前调用setRequestHeader()方法。
post用:
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//表单编码的请求
如今真是说send()方法。先说GET下的send(),
xhr.send();//能够这样 xhr.send(null);//也能够这样,传递一个null,最好设置为null,说有些浏览器不设置为null会报错,因此推荐这样
POST:
xhr.send(msg)//请求的主体要发送内容
以后一次请求就这样被发送到服务器了,接下来就等着响应数据了,来进一步进行操做了。
003:等待响应
可使用XMLHttpRequest对象的一些属性和方法来检测服务器的响应。
首先说readyState属性和readystatechange事件。
redayState属性表示请求或响应过程处于当前的什么阶段了,它是用一个整数表示的0-4。我看见关于这个状态的每一个整数表明的什么状态,说的稍微有点混乱或者说不太明确。我就测试了一下post下的状况,先上测试代码:
window.addEventListener("load",function() { var request = new XMLHttpRequest(); console.log("初始化对象时--" + request.readyState);//0 request.onreadystatechange = function() { console.log("事件--" + request.readyState);//打印每次触发事件时readyState的状态 console.log("服务器--" + request.status); if(request.readyState === 2) { console.log(request.getResponseHeader("Content-Type")); } if(request.readyState === 3) { console.log(request.responseText); } if(request.readyState === 4 && request.status == 200) { console.log(request.getResponseHeader("Content-Type")); // console.log(JSON.parse(request.responseText)); console.log(request.responseText); } } console.log("调用open以前--" + request.readyState);//0 console.log("服务器--" + request.status); request.open("POST","./test.php",true); console.log("调用open以后--" + request.readyState);//1 console.log("服务器--" + request.status); request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8"); console.log("设置头以后--" + request.readyState);//1 console.log("服务器--" + request.status); request.send('aa="aadfd"'); console.log("调用send以后" + request.readyState);//1 console.log("服务器--" + request.status); },false);
<?PHP
header("Content-Type:application/json");//设置响应头的,由于以前测试忘记了就没有删除,因此下面截图里才有application/json;这里没有必要有,只是我测试完了才看见。 echo $_POST['aa']; ?>
chrome截图: IE截图
你能够对照着这张截图看你就明白了,到底这个过程是怎么样的?其实你也不须要太了解这个过程,咱们只对readyState等于4感兴趣。
能够发如今chrome,firefox,opera下的测试结果是,在你实例化XMLHttpRequest对象后,这个状态是0,当你调用了open()方法后这个状态变为了1,这时会触发一个readystatechange事件,你在设置头的时候,这个状态仍是1,在你调用send()方法时,这个状态仍是1,接下来就是靠readystatechange事件来监听了,它会被再触发三次,当这个状态变为2时,就接收到了响应头信息了,当变为3的时候就接收到响应主体了,当4的时候那就响应完成了。
IE稍微有点不一样就是在在设置完头以后,还要触发一次readystatechange事件,其余的都相同
总结readyState值
常量 | 值 | 含义 |
UNSENT | 0 | open()还没有调用 |
OPENED | 1 | open()已经调用 |
HEADERS_RECEIVED | 2 | 接收到头信息 |
LOADING | 3 | 接收到响应主体(内容) |
DONE | 4 | 响应完成 |
readystatechange事件就是在readyState属性值每次变化的时候触发。要是同步的就不须要监听这个事件。
接下来就说说XMLHttpRequest对象的这四个属性:responseText,responseXML,status,statusText,
responseText:得到字符串形式的响应数据(只要不是xml格式的就用这个);
responseXML:得到 XML 形式的响应数据;
status:响应的Http状态;例如200.(这个与readyState的对应关系能够看上面的截图)
statusText:响应的HTTP状态说明,例如ok,其实和status是一个意思,只不过是一个用数字说明,一个用文本说明罢了,200=>ok(这个只有readyState为2,3,4时有值);
最基础的都介绍完了,咱们再来几个完整测试demo。
GET方式:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"> --> <title>php1</title> <script type="text/javascript"> window.addEventListener("load",function() { var btn = document.getElementById("btn"); var content = document.getElementById("content"); btn.addEventListener("click",function() { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if(request.readyState === 4 && request.status == 200) { // console.log(JSON.parse(request.responseText)); content.innerHTML = request.responseText; } } request.open("GET","./test.php",true); // request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8"); request.send(null); }); },false); </script> </head> <body> <input type="button" value="点我" id="btn"> <h2>下面是点击后的内容:</h2> <p id="content"></p> </body> </html>
php:
<?php echo "hello!"; ?>
点击前:
点击后
要是添加查询参数时,只须要修改open()方法的参数;
request.open("GET","./test.php?id=3&a=5",true);
php
<?php echo "你给个人东西是:<br>"; echo 'id是:'.$_GET['id'],"<br>"; echo "a是:".$_GET['a'],"<br>"; if($_GET['id']) { echo 'This is my respone!'; } ?>
点击后:
POST 方式:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"> --> <title>php1</title> <script type="text/javascript"> window.addEventListener("load",function() { var btn = document.getElementById("btn"); var text = document.getElementById("text"); var content = document.getElementById("content"); btn.addEventListener("click",function() { var msg = "id=" + text.value; console.log(msg); var request = new XMLHttpRequest(); request.onreadystatechange = function() { if(request.readyState === 4 && request.status == 200) { var obj = JSON.parse(request.responseText) if(obj['name']){ content.innerHTML = 'name:' + obj['name'] + '<br>' + 'age:' + obj['age']; } else { content.innerHTML = "没有这我的的信息"; } } } request.open("POST","./test.php",true); request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8"); request.send(msg); }); },false); </script> </head> <body> <label>请输入身份id:<input type="text" id="text"></label> <input type="button" value="发送" id="btn"> <h2>下面是点击后的内容:</h2> <p id="content"></p> </body> </html>
php代码:
<?php header("Content-Type:application/json"); if($_POST['id'] == 001) { echo '{"name":"wyl","age":22}'; } else { echo '{}'; } ?>
输入:001前:
输入001,点击后:
输入其余字符点击后:
返回JSON格式的数据记得要用JSON.parse()解析;
POST的send()也能够不传递数据。
还有其余类型数据格式的请求或者响应的,之后有时间再介绍。
到此处最基本的东西应该就这些了。
00x2:XMLHttpRequest level 2:
在HTML5来临的时候,w3c开始将这个XMLHttpRequest对象归入标准中,由于之前就存在了这个对象,如今只是更新了,因此就叫2级XMLHttpRequest;
出现新的版本必定是老的版本有不足:
有如下几点不足:
1.之前只能传输文本数据,不能用来读取和上传二进制文件(好比图片);
2.接收和传递数据时,没有进度信息,只能知道是否传递完成;
3.不能进行跨域请求
新版本(XMLHttpRequest 2)的新特性:
1.能够设置HTTP的请求时限;
2.可使用FormDate对象管理表单数据
3.能够上传文件
4.能够进行跨资源共享(跨域)CORS;
5.有更丰富的进度事件的API
要是介绍完,篇幅太长了,我本身都不看完,都看烦了,有空着再介绍;
参考资料:
犀牛书;红宝书;
http://www.cnblogs.com/skylar/p/ajaxCORS.html
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
http://www.w3school.com.cn/ajax/ajax_intro.asp
http://javascript.ruanyifeng.com/bom/ajax.html
以上是本身结合了不少博客还有书籍总结的,仅表明我的对知识的理解和见解!若有不对的或者不许的地方,欢迎评论指正!