一、什么是AJAX?
用户在浏览器地址栏键入一个网址或者通过网页表单向服务器提交内容,这时浏览器就会向服务器发出HTTP请求,AJAX是指允许脚本向服务器发起HTTP请求。
AJAX包括四个步骤,具体如下:
1、创建AJAX对象
2、发出HTTP请求
3、接收服务器传回的数据
4、更新网页数据
概括起来就是AJAX通过原生的XMLHttpRequest对象发出HTTP请求,得到服务器返回的数据后,再进行处理。
AJAX可以是同步请求,也可以是异步请求。但是,大多数情况下,特指异步请求。因为同步的Ajax请求,对浏览器有“堵塞效应”
二、XMLHttpRequest对象
- XMLHttpRequest对象是Ajax用于进行异步发送请求的核心对象,它用于在后台与服务器进行数据交换
- 通过使用XMLHttpRequest对象,开发者可以:
- 1>在不重新加载页面的情况下更新网页
- 2>在页面已加载后从服务器上请求数据
- 3>在页面已加载后从服务器上接受数据
- 4>在后台向服务器发送数据
- var ajax = new XMLHttpRequest();
- ajax.open('GET','http://www.example.com/page.php',true);
上面代码向指定的服务器网址,发出GET请求。
然后,AJAX指定回调函数,监听通信状态(readyState属性)的变化。
- ajax.onreadystatechange = handleStateChange;
一旦拿到服务器返回的数据,AJAX不会刷新整个网页,而是只更新相关部分,从而不打断用户正在做的事情。
注意,AJAX只能向同源网址(协议、域名、端口都相同)发出HTTP请求,如果发出跨源请求,就会报错。
虽然名字里面有XML,但是XMLHttpRequest可以报送各种数据,包括字符串和二进制,而且除了HTTP,它还支持通过其他协议传送(比如File和FTP)
1、XMLHttpRequest对象的创建
- 现代所有浏览器都内建了XMLHttpRequest对象,不同的浏览器使用的内建方法可能有些许不同,一般来说,总结为三种创建XMLHttRequest对象的语法:
- 1>new XMLHttpRequest(); //window.XMLHttpRequest
- 2>new ActionXObjext(Msxml2.XMLHTTP"); //window.ActiveXObject
- 3>new ActiveXObject("Microsoft.XMLHTTP"); //window.ActiveXObject
- 创建XMLHttpRequest对象的常用代码:
- function createXMLHttpRequest(){
- var xmlhttprequest;
- if(window.XMLHttpRequest)
- xmlhttprequest = new XMLHttpRequest();
- else if(window.ActiveXObject){
- try{
- xmlhttprequest = new ActiveXObject("Mxsml2.XMLHTTP");
- }
- catch(e){
- try{
- xmlhttprequest = new ActiveXObject("Microsoft.XMLHTTP");
- }
- catch(e){
- window.alert("浏览器不支持XMLHttpRequest对象的创建");
- }
- }
- finally{
- return xmlhttprequest;
- }
- }
- }
2、XMLHttpRequest对象的典型用法
- var xhr = new XMLHttpRequest();
- //指定通信过程中状态改变时的回调函数
- xhr.onreadystatechange = function(){
- //通信成功时,状态值为4
- if(xhr.readyState === 4){
- if(xhr.status === 200){
- console.log(xhr.responseText);
- }else{
- console.log(xhr.statusText);
- }
- }
- };
- xhr.onerror = function(e){
- console.error(xhr.statusText);
- };
- //open方式用于指定HTTP动词、请求的网址、是否异步
- xhr.open('GET','/endpoint',true);
- //发出HTTP请求
- xhr.send(null);
3、readyState:是一个只读属性,用一个整数和对应的常量,表示XMLHttpRequest请求当前所处的状态
- 0,对应常量
UNSENT
,表示XMLHttpRequest实例已经生成,但是open()
方法还没有被调用。 - 1,对应常量
OPENED
,表示send()
方法还没有被调用,仍然可以使用setRequestHeader()
,设定HTTP请求的头信息。 - 2,对应常量
HEADERS_RECEIVED
,表示send()
方法已经执行,并且头信息和状态码已经收到。 - 3,对应常量
LOADING
,表示正在接收服务器传来的body部分的数据,如果responseType
属性是text
或者空字符串,responseText
就会包含已经收到的部分信息。 - 4,对应常量
DONE
,表示服务器数据已经完全接收,或者本次接收已经失败了。
在通信过程中,每当发生状态变化时,readyState属性的值就会发生改变。这个值每一次变化,都会触发readyState事件。
4、status:只读属性,表示本次请求所得到的HTTP状态码,如果通信成功的话,这个状态码是200.
基本上,只有2XX和304的状态码,表示服务器返回的是正常状态。
- 200, OK,访问正常
- 301, Moved Permanently,永久移动
- 302, Move temporarily,暂时移动
- 304, Not Modified,未修改
- 307, Temporary Redirect,暂时重定向
- 401, Unauthorized,未授权
- 403, Forbidden,禁止访问
- 404, Not Found,未发现指定网址
- 500, Internal Server Error,服务器发生错误
5、XMLHttpRequest对象的常用方法:
- 1.abort():停止当前请求的发送
- 2.getAllResponseHeaders():获取服务器返回对的全部响应头
- 3.getResponseHeader(name):获取执行的服务器响应头信息
- 4.open(method,url,[,asyncflag,uesrname,password]):与服务器url建立method方式请求连接,
- asyncflag指定是否异步连接,
- username和password指定远程连接服务器的用户名和密码,如果没有则不需要指定
- 5.send(param):指定请求参数,如果使用post方式则将需要传过去的参数使用该方法指定,
- 格式为:send(name1=val1&&name2=val2);如果是get则不需要,直接send(null)
- 6.setRequestHeader(name,value):设置请求头,必须在open()之后、send()之前调用。
- 如果这个方法多次调用,设定同一个字段,则每一次调用的值会被合并成一个单一的值发送。
上面代码首先设置头信息xhr.setRequestHeader('Content-Type', 'application/json'); xhr.setRequestHeader('Content-Length', JSON.stringify(data).length); xhr.send(JSON.stringify(data));
Content-Type
,表示发送JSON格式的数据;然后设置Content-Length
,表示数据长度;最后发送JSON数据。
6、.XMLHttpRequest对象常用的属性:
- 1.onreadystatechange:指定该对象readystate值改变也就是请求的状态改变时的事件处理函数
- 2.readyState:获取该对象的处理状态
- 3.resposneText/resposneXML:获取服务器的响应文本或者响应的XML文档对象
- 4.status:获取服务器返回的响应状态码
- 5.statusText:获取服务器返回的状态文本信息,只有服务器响应完成之后才会有该文本信息
7、实现简单的一步发送请求:
- //异步发送请求的文本form.html
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
- <title>Ajax实现异步请求</title>
- </head>
- <body>
- <form method="psot">
- <label for="username">username</label>
- <input type="text" name="username" id="username" placeholder="please input your username" />
- <br />
- <label for="password">password</label>
- <input type="password" name="password" id="password" placeholder="please input your password" />
- <br />
- <span> </span>
- <button type="submit" id="login">login</button>
- <span> </span>
- <button type="reset">reset</button>
- </form>
- <div id="data">
- </div>
- <!--js start-->
- <script>
- window.onload = function(){
- var login = document.getElementById('login');
- login.onclick = function(){
- //create xmlhttprequest
- var ajax = new XMLHttpRequest();
- //send request
- var username = document.getElementById('username').value;
- var password = document.getElementById('password').value;
- ajax.open('post','test.php',true);
- var data = 'username='+username+"&password="+password;
- ajax.send(data);
- //receive data from server
- ajax.onreadystatechange = function(){
- if(ajax.readyState == 4 && ajax.status == 200){
- var serverdata = ajax.responseText;
- document.getElementById('data').innerHTML = serverdata;
- }
- };
- return false;
- };
- };
- </script>
- <!--js end-->
- </body>
- </html>
- //服务器url的响应文件server.php
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
- <title>php站点测试文件</title>
- </head>
- <body>
- <?php
- echo "have received the data from client";
- ?>
- </body>
- </html>
- //最终结果:点击login之后不用刷新页面将会在#data div下显示php文件传入的信息
8、load事件、error事件、abort事件
load事件表示服务器传来的数据接收完毕,error事件表示请求出错,abort事件表示请求被中断。
abort
、load
和error
这三个事件,会伴随一个loadend
事件,表示请求结束,但不知道其是否成功。
var xhr = new XMLHttpRequest();
xhr.addEventListener("progress", updateProgress);
xhr.addEventListener("load", transferComplete);
xhr.addEventListener("error", transferFailed);
xhr.addEventListener("abort", transferCanceled);
xhr.open();
function updateProgress (oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded / oEvent.total;
// ...
} else {
// 回应的总数据量未知,导致无法计算百分比
}
}
function transferComplete(evt) {
console.log("The transfer is complete.");
}
function transferFailed(evt) {
console.log("An error occurred while transferring the file.");
}
function transferCanceled(evt) {
console.log("The transfer has been canceled by the user.");
}