代码改变世界

javascirpt系列之 - XMLHttpRequest对象

2013-05-14 23:36  MoltBoy  阅读(1790)  评论(7编辑  收藏  举报

  最近在做一个关于Ajax的项目,项目本身非常简单,但是接手项目之时,设计了过多的特效,导致为了兼容不得不让代码几何增加。设计项目设计图之时也过于简单潦草,不过总算完成任务,但不能就此了之,必须得挤些时间出来回顾和总结,将好的一些经验和不足之处分别进行记录,避免同一个地方跌倒两次。

   进入正题,XMLHttpRequest对象其实是浏览器的一个标准接口,主要通过http协议与后台服务器交换数据,可惜地是这个接口一直没有得到W3C的标准化,直到HTML5的概念出现。不过,2008年2月份,已经提出了XMLHttpRequest Level 2的草案。

  创建XMLHttpRequest

  通过XMLHttpRequest对象发送HTTP请求至少需要以下几个步骤(当然还可以采取更多的其他步骤):

  1. 创建一个XMLHttpRequest对象,目前没有跨浏览器的创建方法;
  2. 指定新创建的XHR对象打开一个特定的文件,也就是调用open()方法;
  3. 通知对象如何处理响应的数据,也就是注册onreadystatechange事件处理程序;
  4. 让对象发送请求,调用send()方法。

  路要一步一步走,先创建一个XMLHttpRequest对象。在这里提供一个能兼容绝大部分现存浏览器的方法。

function createXHR(){
      if(typeof XMLHttpRequest != "undefined"){
            return new XMLHttpRequest();
      } else if (typeof ActiveXObject != "undefined") {
           var vers = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp.2.0"];
           for (var i = 0, len = vers.length; i < len; i++) {
                try {
                    var xhr = new ActiveXObject(vers[i]);
                    return xhr;
                } catch (ex) {
                    alert("Function createXHR error: " + ex.message);
            continue; } } }
else { throw new Error("No XHR object available."); } }

  不能兼容的主要是IE,因为在早期的IE版本中,这个对象是一个ActiveX对象。"MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp.2.0",这些都是ActiveX对象名称,具体用哪个取决于用户的windows配置,而不是浏览器决定。里面使用了try/catch语句,如果创建成功,就返回此对象,若不存在的否则进入下一次循环继续创建。

  打开请求

  下一步,打开一个新请求,这是为发送请求做准备,真正的发送指令是send()。

  open()方法包含三个参数,第一个参数定义为请求的方式:GET、POST、PUT、HEAD等,前面两个是最常用的,这些方式不区分大小写,但是通常都以大写形式出现,以匹配HTTP协议。GET是把数据作为查询字符串追加在URL上,传送给服务端,适用于常规请求,例如:URL完全指定了请求资源,或者请求对服务器没有副作用以及服务器响应可缓存之时;POST是让数据随着HTTP请求的正文发送,也就是写入body内,通常用于发送HTML表单信息,而且是非幂等的,也就是说相同的URL的重复POST请求从服务器端得到的响应可能不同,同时不应该缓存使用这个方法的请求。  

var xhr = createXHR();
xhr.open(type, url, isAsy);     

  HEAD方式使用比较少见,此请求只返回响应的HTTP头部,而非响应的主体,可以用来显示文件的最后的修改日期。另外,使用POST方法时,必须记得设置请求的内容类型,这点经常容易忘记,这次有位组成员也犯了此错误,不过调试一下,很容易追踪到这类的错误。(Content-Type: [type]/[subtype]; parameter)type常用的几种形式Text、Application、Image、Message、Audio、Video等,subtype用于指定type的详细形式,例如:  

  • text/plain(纯文本)
  • text/html(HTML文档)
  • application/xhtml+xml(XHTML文档)
  • image/gif(GIF图像)
  • image/jpeg(JPEG图像)【PHP中为:image/pjpeg】
  • image/png(PNG图像)【PHP中为:image/x-png】
  • video/mpeg(MPEG动画)
  • application/octet-stream(任意的二进制数据)
  • application/pdf(PDF文档)
  • application/msword(Microsoft Word文件)
  • multipart/alternative(HTML邮件的HTML形式和纯文本形式,相同内容使用不同形式表示)
  • application/x-www-form-urlencoded(使用HTTP的POST方法提交的表单)
  • multipart/form-data(同上,但主要用于表单提交时伴随文件上传的场合)

  url参数时访问服务端数据的URI,叠加查询字符串也需要用到,最后的isAys是通知浏览器是否需要异步的布尔值,true为异步,false为同步,缺省值为false。异步也即是说,在进行某些需要比较长时间的操作时,浏览器不必等到服务端的数据返回,而是立即执行后面的代码,接触过回调函数的TX很容易理解这点。反之,则需要无聊地等待。当然,绝大部分情况下,都是用true,要不然没必要是用XHR。

  注册处理事件程序

  接着,需要先注册readystatechange事件处理程序,必须在open()方法之后,send()方法之前。事件处理程序也就是根据服务端返回的readystate进行判断,是否可以进行响应的数据处理。readystatechange事件一共五个就绪的状态,web开发者必须得将它们熟烂在肚子里。

数值 意义 详细描述
0 未初始化(UNSENT) 已经创建了XHR对象,但未调用open()
1 加载中(OPENED) 已经创建了XHR对象,但未调用send()
2 已加载(HEADERS_RECEIVED) 已调用send(),但是状态和头信息还不可以使用
3 交互中(LOADING) 已经接受到了部分数据信息
4 完成(DONE) 所有的数据接受完成,全部可以使用

  就绪状态4最为常见,意思为可以使用response对象的数据信息。

  发送操作

  紧接着,调用send()方法,send方法需要一个参数,若是POST方法,参数就是传递的数据,也就是body内容;若是GET方法,参数就是null。发送请求后,等待响应到达。(此处未考虑多个request异步并发)一旦到达,onreadystatechange事件处理程序就被激发,并按照指示执行事情。

  时间关系,未完待续....(已经11:35)

 参考资料:http://www.w3.org/Protocols/rfc2616/rfc2616.html