HTTP天堂:XMLHTTPReuqest 全解析

/**
 * @author 《JavaScript权威指南》,蓝文雄解读整理

 * 声明:时间精力水平有限,本文档存在错误

 * 但依然可作为思路文档使用,实际开发可使用我封装的

    http://www.cnblogs.com/vincent-lwx/archive/2008/08/19/1270998.html
 * 第一步:创建XMLHTTPReuqest对象
 * 第二步:指定XMLHTTPReuqest三种请求
 * 第三步:同步或异步获取并处理服务器响应(响应处理参考以下文档说明)
 *
 * XMLHTTPReuqest.open():第三个参数为true(默认)/false--异步/同步(可选):
 *
 * (1)同步请求
 *     采用队列请求方式。与异步不同,无需考虑请求状态码的改变,只需判断HTTP状态代码:
 *      if(request.status==200){ 
 *       if(request.getResponseHeader("Content-Type")=="text/xml"){
     var doc=request.responseXML;
    }
   }
   else{
    alert("Error"+request.status+":"+request.statusText);
   }
   
 * (2)异步请求
 *     需要指定onreadystatechange:0(open()没有调用)、1(open()调用但send()没发送)、2(send()调用但服务器没响应)、3(正在接受服务器端数据,因浏览器而异)
 *     由于浏览器支持的差异性只考虑readyState==4(特别readyState==3,firefix多次调用onreadystatechange时间句柄,而IE没有)
 *     异步请求、处理响应参考各个工具函数
 *
 *  本文档介绍了处理不同编码的响应方式
 *  本文档介绍了使请求过期的方法
 */

 

/**
 * XMLHTTPReuqest跨平台请求工具函数
 */

 

HTTP._factories=[   //针对不同浏览器的XMLHttpRequest对象数组
 function(){return new XMLHttpRequest();},
 function(){return new ActiveXObject("Msxml2.XMLHTTP");},
 function(){return new ActiveXObject("Microsoft.XMLHTTP");}
];

HTTP._factory=null;

HTTP.newRequest=function(){
 if(HTTP._factory!=null) return HTTP._factory();
 for(var i=0;i<HTTP._factories.length;i++){
  try{
   var factory=HTTP._factories[i];
   var request=factory();
   if(request!=null){
    HTTP._factory=factory;
    return request;  //成功创建XMLHttpRequest
   }
  }
  catch(e){
   continue;
  }
 }
 
 HTTP._factory=function(){
  throw new Error("XMLHTTPRequest not supported!");  //浏览器不支持XMLHttpRequest,抛出错误
 }

 HTTP._factory();
}

/**
 * HTTP.GET两个工具函数:分别获取text、xml响应
 * callback:处理响应文本、xml的函数(需手工建立)
 */

HTTP.getText=function(url,callback){
 var request=HTTP.newRequest();
 request.onreadystatechange=function(){
  if(request.readyState==4 && request.status==200)
   callback(request.responseText);   //请求正常,callback函数托管响应
 } 
 request.open("GET",url);
 request.send(null);
}

HTTP.getXML=function(url,callback){
 var request=HTTP.newRequest();
 reuqest.onreadystatechange=function(){
  if(request.readyState==4 && request.status==200)  //请求成功
   callback(request.responseXML);   //请求正常,callback函数托管响应
 } 
 request.open("GET",url);
 request.send(null);
}

/**
 * HTTP.getHeaders()工具函数:请求获取HTTP头部并解析HTTP头部键值对并存储为一个JavaScript对象的属性和值
 * callback:处理HTTP.parseHeaders函数返回的JavaScript对象(需手工建立)
 * errorHandler:错误句柄函数,处理404或者其他错位代码(需手工建立)
 * HTTP.parseHeaders:解析HTTP头部键值函数,返回JavaScript对象
 * */

HTTP.getHeaders=function(url,callback,errorHandler){
 var request=HTTP.newRequest();
 reuqest.onreadystatechange=function(){
  if(request.readyState==4){
   if(request.status==200){
    callback(HTTP.parseHeaders(request));  //请求正常,HTTP.parseHeaders函数托管响应
   }
  }else{
   if(errorHandler) errorHandler(request.status,request.statusText);  //请求异常
   else callback(null);
  }    
 } 
 request.open("HEAD",url);
 request.send(null);
};

HTTP.parseHeaders=function(request){
 var headerText=request.getAllResponseHeaders();  //获取头部键值数组
 var headers={};  //返回值
 var ls=/^\s*/;  //正则表达式
 var ts=/\s*$/;
 
 var lines=headerText.split("\n");
 for(var i=0;i<lines.length;i++){
  var line=lines[i];
  if(line.length==0) continue;  //忽略空行,否则开始解析
  var pos=line.indexOf(':');
  var name=line.substring(0,pos).replace(ls,"").replace(ts,"");
  var value=line.substring(0,pos+1).replace(ls,"").replace(ts,"");
  headers[name]=value;  //填充返回值
 }
 return headers;
};

/**
 * HTTP.POST()工具函数:基本形式与HTTP.getHeaders()类似,但需要设置请求头部信息、请求体数据
 * HTTP.encodeFormatData:格式化并返回请求体数据
 * HTTP._getResponse:处理响应,参考以下文档说明
 * */

HTTP.post=function(url,callback,errorHandler){
 var request=HTTP.newRequest();
 reuqest.onreadystatechange=function(){
  if(request.readyState==4){
   if(request.status==200){
    callback(HTTP._getResponse(request));  //请求正常
   }
  }else{
   if(errorHandler) errorHandler(request.status,request.statusText);  //请求异常
   else callback(null);
  }    
 } 
 request.open("POST",url);   //指定请求格式,并且设置请求头部信息
 request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
 request.send(HTTP.encodeFormatData(values)); 
 //HTTP.encodeFormatData(values)函数返回请求体数据
};

HTTP.encodeFormatData=function(data){
 var pairs=[];
 var regexp=/%20/g;
 
 for(var name in data){
  var value=data[name].toString();
  var pair=encodeURIComponent(name).replace(regexp,"+")+
  '='+encodeURIComponent(value).re.replace(regexp,"+");
  pairs.push(pair);
 }
 return pairs.join('&');
};

/**
 * 处理请求响应:TEXT\HTML\XML\JSON编码
 * XML响应:服务器必须使用MIME类型的"text/xml"标示XML文档,保证XMLHttpRequest把响应XML解析为doxument对象中,然后使用DOM方法处理
 * HTML响应:和TEXT一样使用request.responseText访问,然后使用文档元素innerHTML属性处理
 * JSON响应:使用eval()解析JSON编码的数据,注意安全问题,防止服务器发送恶意的可执行的脚本!安全的方法是使用JSON解码器(http://json.org/)。
 * 下面提供一个简单的通用文档
 * */

HTTP._getResponse=function(request){
 switch(request.getRequestHeader("Content-Type")){
  case "text/xml":
   return request.responseXML;
  case "text/json":
  case "text/javascript":
  case "application/javascript":
  case "application/x-javascript":
   return eval(request.responseText);
  default:
   return request.responseText;
 }
}

/**
 * 在某些场景中需要手动设置请求的过期,而XMLHttpRequest没有提供如此的方法
 * XMLHttpRequest发布HTTP请求时,使用window.setTimeout()设置过期值和window.clearTimeout()取消过期设置
 * 使用XMLHttpRequest.abort()取消请求
 * 现在提供一个工具函数HTTP.get():展示过期技术(options)的使用,同时整合了前面部分工具函数的功能
 * 特色:允许调用者指定可选的回调函数,当onreadystatechange句柄使用4以外的其他readyState值被调用时,触发这个回调函数
 * (Firefix在状态3中多次调用这个句柄onreadystatechange向用户显示下载反馈)
 * */

HTTP.get=function(url,callback,options){
 var request=HTTP.newRequest();  //创建XMLHttpRequest对象
 var n=0;
 var timer;
 if(options.timeout)  //请求过期设置
  timer=setTimeout(function(){
   request.abort();
   if(options.timeoutHandler)
    options.timeoutHandler(url);
  },
   options.timeout);
   
 request.onreadystatechange=function(){  //状态改变处理函数
  if(request.readyState==4){  //服务器响应完成
   if(timer) clearTimeout(timer);  //清除过期设置
   if(request.status==200){  //请求成功开始处理响应
    callback(HTTP._getResponse(request));
   }
   else{
    if(options.errorHandler)  //请求失败开始处理失败句柄
     options.errorHandler(request.status,request.statusText);
    else callback(null);
   }
  }
  else if(options.progrressHandler){  //如果指定状态值<4时的请求过程处理句柄
   options.progressHandler(++n);   //0(open()没有调用)、1(open()调用但send()没发送)、2(send()调用但服务器没响应)、3(正在接受服务器端数据,因浏览器而异)
  }
 }
 
 var target=url;
 if(options.parameters)  //如果请求有参数需要发送,构造请求url
  target += "?" + HTTP.encodeFormatData(options.parameters);
 request.open("GET",target);
 request.send(null);
 
};

 

 

 

 

 

 

 

 

 

 

 


 

转载于:https://www.cnblogs.com/vincent-lwx/archive/2008/08/08/1263658.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值