JavaScript Ajax之美

曾经有一段时期,由于开发人员对JavaScript的滥用致使其遭受了一段时间的冷门时期,不被你们看好,后来,到了2005年,Google公司的不少技术都是用了ajax以后,JavaScript才又火热了起来,能够说,是Ajax拯救了JavaScript,就目前来讲,熟练使用Ajax已经成为了全部web开发人员必须掌握的技能。那么Ajax又是什么呢? 它的做用是什么呢?javascript

第一部分:Ajax简介

  Ajax即Asynchronous JavaScript +XML的简写,这一技术可以向服务器请求额外的数据而无需卸载页面,会带来更好地用户体验。Ajax的核心是XMLHttpRequest对象(简称XHR,这一对象受到chrome、safari、FF、opera等主流浏览器的支持),这是由微软首先引入的一个特性,IE 浏览器使用 ActiveXObject,后来浏览器提供商都提供了相同的实现。XHR对象的存在,意味着当用户点击以后,没必要刷新页面也能够从后台取得新数据,也就是说,能够试用XHR对象取得新数据,而后经过DOM方式将新数据插入到页面中,达到对网页的某部分进行更新的效果。值得注意的是:虽然,Ajax中包含了xml,可是咱们在无需刷新页面就获得的数据不必定是xml数据。php

 

第二部分:XHR对象的建立

  上面讲到,Ajax的核心是XMLHttpRequest对象,那么咱们如何建立一个XMLHttpRequest对象呢?html

  首先,咱们应当知道:全部浏览器都支持XMLHttpRequest对象,其中IE5和IE6使用ActiveXObject对象。而且如今全部浏览器(IE7+、FireFox、Chrome、Safari以及Opera)均内建了XMLHttpRequest对象。因而建立XMLHttpRequest对象的语法是:java

1
var  xhr =  new  XMLHttpRequest();

   

  刚刚提到老版本的Internet Explorer(IE5和IE6)使用的是ActiveXObject对象,因此语法是:web

1
var  axo =  new  ActiveXObject( "Microsoft.XMLHTTP" );

  注意:其中传入的“Microsoft.XMLHTTP”是不能改变的。ajax

 

  因而,为了应对全部的现代浏览器(包括IE5和IE6),请首先检查是否支持XMLHttpRequest对象:若是支持,则建立XMLHttpRequest对象;若是不支持,则建立ActiveXObject对象:chrome

1
2
3
4
5
6
7
8
9
var  xmlHttp= null ;
if (window.XMLHttpRequest)
{  
     xmlHttp= new  XMLHttpRequest();
}
else
{
     xlmHttp= new  ActiveXObject( "Microsoft.XMLHTTP" );
}

  关于这个应对全部现代浏览器的代码应当注意:跨域

  • 我将xmlHttp的值设置为null,是由于null值表示一个空对象指针,而这也正是使用typeof操做符检测null值是会返回“object”的缘由,所以:若是定义的变量准备在未来用于保存对象,那么最好将该变量初始化为null而不是其余值。
  • 之因此能够试用window.XMLHttpRequest来检测其是否存在,是由于XMLHttpRequest是window对象的属性。

 

第三部分:XHR对象的用法(属性与方法等)

  上面两部分,咱们介绍XHR对象是什么以及怎么建立,这一部分我将谈一谈XHR对象的用法。浏览器

  ⑴.open()方法缓存

  既然XHR是一个对象,那么它就必定有本身的属性和方法。在使用XHR对象时,要调用的第一个方法是open()。它接受3个参数:

  1. 要发送的请求的类型:get、post、put、delete等等。
  2. 请求的URL(这个URL既能够是绝对路径,也能够是相对路径)。
  3. 是否异步发送请求的布尔值:true表示异步发送请求,false表示同步发送请求。

   举例以下:

1
xhr.open( "get" , "example.php" , true );

  此时,这段代码会启动一个针对example.php的GET请求。注意:open()方法并不会真正的发送请求而只是启动一个请求以备发送。那么怎么才能发送特定的请求呢,这是就要用到send()方法了。

  

  ⑵.send()方法

  刚刚说到open()方法,只是开启(open),尚未发送,而send才是真正地发送。它接受一个参数:

  • 做为请求主体发送的数据

  注意:若是不须要经过请求主体发送数据,则必须传入null。通常get请求不须要传入参数,而对于post请求,若是须要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。而后在 send() 方法中规定您但愿发送的数据。这一部分会详细介绍,下面举一个简单例子:

 

1
2
xhr.open( "get" , "example.php" , true );
xhr.send( null );

 

  

 

  (3).XHR对象的几个属性

  经过send()发送以后,会接受到响应,响应的数据会自动填充XHR对象的属性。主要有如下几种:

  • responseText:做为响应主体被返回的文本
  • responseXML:若是响应的内容类型是"text/xml"或"application/xml",这个属性中将保存包含着相应数据的XML DOM文档。
  • status:响应的http状态
  • statusText:Http状态的说明

  在接收到响应后,通常是先检查status属性,来肯定响应是否成功返回,通常状态代码200表示成功(以2开头即表示成功),这是responseText就能够被访问了。而状态代码为304表示请求的资源并无被修改,能够直接使用浏览器中缓存的版本,所以这种响应也是有效的。因而能够经过下面的代码检测这两种状态:

1
2
3
4
5
6
7
xhr.open( "get" , "example.php" , false );
xhr.send( null );
if ((xhr.status>=200&&xhr.status<300)||xhr.status==304){
     alert(xhr.responseText);
} else {
     alert( "Request waw unseccessful:" + "xhr.status" );
}

  

  XHR对象的readystate属性

  使用Ajax咱们固然仍是但愿发送异步请求的:若是发送同步请求,那么一旦网卡住了,这个页面就不会有任何反应而是继续等待响应,可是发送异步请求,即便网卡住,也不用担忧,由于它是异步的。而readystate属性能够检测到请求/响应过程的当前活动阶段。它有5个取值,分别以下:

 

    

  关键:只要readystate的值改变(好比从0变为1,从1变为2等等),那么每次地改变都会触发readystatechange事件。而且能够经过这个时间检测每次状态变化后的readystate的值。当值为4是最重要的,由于这事全部的数据已经准备就绪。看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
var  xhr= new  XMLHttpRequest();
xhr.open( "get" , "example.php" , false );
xhr.onreadystatechange= function (){
     if (readystate==4){
         if ((xhr.status>=200&&xhr.status<300)||xhr.status==304){
             alert(xhr.responseText);
         } else {
             alert( "Request waw unseccessful:" + "xhr.status" );
         }
     }
};
xhr.send( null );

   注意如下几点:

  • xhr.onreadystatechange前面有一个on,这是由于咱们使用的是DOM0级方法为XHR对象添加了时间处理程序,没有利用addEventListener这种DOM2级方法,是由于并不是全部的浏览器都支持DOM2级方法
  • 这个例子中咱们没有使用this对象,是由于onreadystatechange时间处理程序的做用域问题。若是使用this对象,在有的浏览器中会致使函数执行失败或者致使发生错误。所以,使用实际的XHR对象实例便利那个是一种较为可靠的方式。

 

  (4).abort()方法

  在接受到响应以前,咱们还可使用abort()方法来取消异步请求,以下所示:

1
xhr.abort();

  在调用了这个方法以后,XHR对象会中止触发事件,并且也再也不容许访问任何与响应有关的对象属性。

  (5)setRequestHeader()方法、getResponseHeader()方法、getAllResponseHeader()方法在第四部分介绍完以后讲解

 

第四部分:HTTP头部信息

  由于使用Ajax和后台交互,那么就必定离不开http协议了。而HTTP请求和响应都会带有相应的头部信息。

  在默认状况下,在发送XHR请求的同时,还会发送如下头部信息。

  • Accept:浏览器可以处理的内容类型
  • Accept-Charset:浏览器可以显示的字符集
  • Accept-Encodding:浏览器可以处理的压缩编码
  • Accept-Language:浏览器当前设置的语言
  • Connection:浏览器与服务器之间连接的类型
  • Cookie:当前页面设置的任何Cookie
  • Host:发出请求的页面所在的域
  • Referer:发出请求页面的URI
  • User-Agent:浏览器的用户代理字符串   

  下面这张图片是个人chrome浏览器开发者工具下的network中截屏所得,你们能够对照参考:

 

  咱们还能够经过setRequestHeader()方法来设置自定义的请求头部信息。这个方法接收两个参数:头部字段的名称和头部字段的值。而且咱们必须在open()方法以后,在send()方法以前来调用setRequestHeader()方法。举例以下:

1
2
3
4
var  xhr= new  XMLHttpRequest();
xhr.open( "get" , "example.php" , true );
xhr.setRequestHeader( "myHeader" , "myValue" );
xhr.send( null );

  这里只须要注意:这里传入的头部字段的名称最好是自定义的,而不要使用浏览器正常发送的字段名称,不然有可能会影响浏览器的响应。(由于有的浏览器容许开发人员重写默认的头部信息,而有的浏览器是不容许开发人员重写默认的头部信息的)。

  除了能够为请求头部增长自定义的头部字段,咱们还能够获取头部字段。咱们能够调用XHR对象的getResponseHeader()方法并传入一个头部字段名称,即可以得到响应头部信息。还能够调用XHR对象的getAllResponseHeaders()方法取得一个包含全部头部信息的长字符串。

  以下所示:

1
2
var  myHeader=xhr.getResponseHeader( "myHeader" );
var  allHeaders=xhr.getAllResponseHeaders();

  

 

第五部分:GET请求

  get请求用于向服务器查询某些信息。注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的。 可是,有时候可能会出现问题,即查询字符串的格式有问题。查询字符串的每一个参数的名称和值都必须使用encodeURIComponent()进行编码,而后才能放到URL的末尾;并且全部的名值对都必须用&分隔。以下所示:

1
xhr.open( "get" , "example.php?name1=value1&name2=value2" , true );

  而下面的这个函数能够辅助向现有的URI的末尾添加查询字符串:

1
2
3
4
5
6
7
8
9
function  addURIParam(url,name,vaule){
     url+=(url.indexOf( "?" )==-1? "?" : "&" );
     url+=encodeURIComponent(name)+ "=" +encodeURIComponent(value);
     return  url;
}
var  url= "example" ;
url=addURIParam(url, "name" , "zzw" );
url=addURIParam(url, "sex" , "male" );
xhr.open( "get" ,url, false );

  实际上,函数中的第一句是先判断url后面有没有查询字符串,若是没有,就添加?,若是有,就添加&,所以,最终的url为"example.php?name=zzw&sex=male"。

  另外,对于get请求须要注意:

  • GET请求能够被缓存
  • GET请求保留在历史记录中
  • GET请求可悲收藏为书签
  • GET请求不该该在处理敏感数据时使用(由于查询字符串是暴露的,任何人均可以看到)
  • GET请求有长度限制,超过最大长度后通常没法提交,更多看这里
  • GET请求只应当用于取回数据

 

第六部分:POST请求

  POST请求的使用频率仅次于GET请求,一般用于向服务器中发送应该被保存的数据。请注意,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的。而GET请求却不是这样的。POST请求的主体能够包含不少的数据,并且格式不限。

  默认状况下,服务器对post请求和提交web表单的请求不会一视同仁,所以,咱们能够试用XHR对象和模仿表单提交:首先将Content-Type头部信息设置为application/x-www-form-urlencoded,也就模仿成了表单提交时的内容类型(赞一个!)。接着须要在以适当的格式建立一个字符串,post数据的格式和查询字符串格式相同,若是须要将页面中表单的数据序列化,在经过XHR发送到服务器,那么就要使用serialize()函数来建立这个字符串。下面举两个例子:

  

1
2
3
xhr.open( "POST" , "example.php" , true );
xhr.setRequestHeader( "Content-type" , "application/x-www-form-urlencoded" );
xhr.send( "fname=Bill&lname=Gates" );

 这里咱们没有将字符串序列化。

1
2
3
4
xhr.open( "POST" , "example.php" , true );
xhr.setRequestHeader( "Content-type" , "application/x-www-form-urlencoded" );
var  form=document.getElementById( "user-info" );
xhr.send(serialize(form));

 这里咱们使用serialize()函数进行了序列化。

   另外,对于post请求须要注意:

  • POST请求不会被缓存
  • POST请求不会保留在浏览器历史记录中
  • POST请求不能被收藏为书签
  • POST请求对数据长度没有要求

 

 

讲过了POST请求和GET请求,那么它们之间的区别是什么呢?

 

第七部分:同源策略

  经过XHR实现Ajax通讯的一个主要限制,来源于跨域安全策略,又称为同源策略。那么什么使同源策略呢?

  同源策略,它是由Netscape提出的一个著名的安全策略,默认状况下,XHR对象只能访问与包含他的页面位于同一个域中的资源,这种安全策略能够预防某些恶意行为。如今全部支持JavaScript的浏览器都会使用这个策略,这种安全策略能够预防某些恶意行为,好比,A网站是一家银行,若是用户登录了之后,其余的网站能够读取A网站的Cookie,那么其余网站就能够随心所欲了。可是,实现合理的跨域请求对开发某些浏览器的应用程序也是相当重要的。后续的文章我会介绍跨域资源共享的知识。这里仅介绍同源策略。

  所谓同源是指:协议、域名和端口相同

  举例说:http://www.cnblogs.com/dir/page.html这个网址。

  协议:http://

  域名:www.cnblogs.com

  端口:80(默认端口能够省略)。

  对于这个网址的同源状况以下:

  • http://www.cnblogs.com/cat/index.html (同源)
  • http://cnblogs.com/dir/page.html(不一样源-域名不一样)
  • https://cnblogs.com/dir/page.html(不一样源-协议不一样)
  • http://www.cnblogs.com:81/dir/page.html(不一样源-端口不一样)
相关文章
相关标签/搜索