首页 > 代码库 > 脚本化HTTP
脚本化HTTP
Ajax:AsynchronousJavaScript and XML:异步Javascript和XML:ajax描述了一种主要使用脚本操纵HTTP的Web应用架构。其主要特点是:使用脚本操纵HTTP和Web服务器进行数据交换,不会导致页面重载。
<iframe>元素更加强大,为了把<iframe>作为ajax传输协议使用,脚本首先要发送给Web服务器的信息编码到URL中,然后设置<Iframe>的src属性为该URL。服务器能够创建个包含响应内容的HTML文档,并把它返回Web服务器,并且在<iframe>中显示它。脚本通过遍历<iframe>的文档对象来读取服务端的响应。注意:这受限于同源策略。
<script>元素的src属性设置URL并发起HTTP GET请求。使用<script>元素实现脚本操纵HTTP是非常吸引人的,因为他们可以跨域通信而不受限于同源策略。通常,使用基于<script>的Ajax传输协议时,服务器的响应采用Json编码的数据格式,当执行脚本时,JavaScript解析器能自动将其“解码”。由于使用JSON数据格式,因此这种Ajax传输协议也叫做“JSONP”。
IE5和IE6不支持XMLHttpRequest对象,不过它支持一个ActiveX对象,以下提供一个在IE5和IE6中模拟XMLHttpRequest()构造函数的方法
if(window.XMLHttpRequest===undefined){
window.XMLHttpRequest=function(){
try{//如果可用,则使用ActiveX对象的最新版本
return newActiveXObject("Msxml2.XMLHTTP.6.0");
}catch(e1){
try{//否则,退回到较旧的版本
return newActiveXObject("Msxml2.XMLHTTP.3.0");
}catch(e2){//否则,抛出异常
throw newError("XMLHttpRequest is not surpported");
}
}
}
}
5.一个HTTP请求由4部分组成:1)HTTP请求方法或“动作”(verb);2)正在请求的URL;3)一个可选的请求头集合,其中可能包括身份验证信息;4)一个可选的请求主体。服务器返回的HTTP响应包含3部分:1)一个数字和文字组成的状态码,用来显示请求的成功或失败;2)一个响应头集合;3)响应主体。
6.HTTP请求的各部分有指定顺序:请求方法和URL首先到达,然后是请求头,最后是请求主体。XMLHttpRequest实现通常直到调用send方法才开始启动网络。但XMLHttpRequest API的设计似乎使每个方法都将写入网络流。这意味着调用XMLHttpRequest方法的顺序必须匹配HTTP请求的架构。例如,setRequestHeader()方法的调用必须在调用open()之后但在调用send()之前,否则它将抛出异常。
7.一个完整的HTTP响应由状态码、响应头集合和响应主体组成。这些都可以通过XMLHttpRequest对象的属性和方法使用:
1) status和statusText属性以数字和文本的形式返回HTTP状态码。这些属性保存标准的HTTP值
2) 使用getResponseHeader()和getAllResponseHeaders()能查询响应头。XMLHttpRequest会自动处理cookie:它会从个tAllResponseHeaders()头返回集合中过滤掉cookie头,而如果给getResponseHeader()传递“Set-Cookie”和“Set-Cookie2”则返回null。
3) 响应主体可以从responseText属性中得到文本形式的,从responseXML属性中得到Document形式的。
8.readyState是一个整数,它指定了HTTP请求的状态,如下表,第一列的符号是XMLHttpRequest构造函数定义的常量。这些常量是XMLHttpRequest规范的一部分,但老的浏览器和IE8没有定义他们,通常看到使用硬编码值4来表示XMLHttpRequest.Done
理论上,每次readyState属性改变都会触发readystatechange事件。实际上readyState改变为0或1时,可能没有触发这个事件。当调用send()时,即使readystate仍然处于OPENED状态,也通常会触发它。某些浏览器在LOADING状态时触发多次事件来给出进度反馈。当readyState值改变为4或浏览器的响应完成时,所有的浏览器都触发readystatechange事件。因为在响应完成之前会触发事件,所以事件处理程序应该一直检验readyState值。
9.可以通过将XMLHttpRequest对象的open方法中的最后一个参数设为false来实现发送同步请求。
10.提供一个对象属性的表单编码函数:
functionencodeFormData(data){
if(!data) return "";
var pairs=[];
for(var name in data){
if(!data.hasOwnProperty(name))continue;//跳过继承属性
if(typeofdata[name]==="function") continue;//跳过方法
var value=http://www.mamicode.com/data[name].toString();
name=encodeURIComponent(name.replace("%20","+"));
value=http://www.mamicode.com/encodeURIComponent(value.replace("20%",+));
pairs.push(name+"="+value);
}
return pairs.join("&");
}
11.使用JSON编码主体来发送HTTP POST请求:
functionpostJSON(url,data,callback){
var request=new XMLHttpRequest();
request.open("POST",url);
request.onreadystatechange=function(){
if(request.readyState===4&&callback){//当响应完成时
callback(request);
}
};
request.setRequestHeader("Content-Type","application/json");
request.send(JSON.stringify(data));
}
12.上传文件:以下提供一个HTTP POST请求上传文件
//查找有data-uploadto属性的全部<input type=”file”>元素
//并注册onchange事件处理程序
//这样任何选择的文件都会自动通过POST方法发送到指定的“uploadto”的URL
//服务器的响应式忽略的
whenready(function(){
varelts=document.getElementsByTagName("input");
for(var i=0;i<elts.length;i++){
var input=elts[i];
if(input.type!=="file")continue;//跳过非文件上传元素
varurl=input.getAttribute("data-uploadto");//获取上传URL
if(!url) continue;//跳过没有任何URL的元素
input.addEventListener("change",function(){
var file=this.files[0];//假设单个文件选择
if(!file) return;
var xhr=new XMLHttpRequest();
xhr.open("POST",url);
xhr.send(file);
},false);
}
})
13.HTTP进度事件:XHR2规范草案定义了更多有用的事件集,有已经在Firefox、Chrome和Safari中得到支持。在这个新的事件模型中,XMLHttpRequest对象在请求的不同阶段触发不同类型的事件,所以它不再需要检查readyState属性。在支持它们的浏览器中,这些新事件会像如下这样触发。当正在加载服务器的响应时,XMLHttpRequest对象会发生progress事件,通常每个50秒左右,所以可以使用这些事件给用户反馈请求进度。如果请求快速完成,他们可能从不会触发progress事件。当事件完成时,会触发load事件。
HTTP请求无法完成有三种情况,对应3种事件。如果请求超时,会触发timeout事件。如果请求终止,会触发abort事件。最后像太多重定向这样的网络错误会阻止请求的完成,但这些情况会触发error事件。如果正常完成则触发load事件。
只要以上中的一个触发,浏览器就会触发loadend事件。
progress事件相关联的事件对象还有3个有用的属性。loaded属性时目前传输的字节数值。total属性自“Content-Length”头传输的数据的整体长度(单位是字节),如果不知道内容长度则为0。最后,如果知道内容长度则lengthComputable属性为true,否则为false。显然,total和loaded属性对progress事件处理程序相当有用。
14.终止请求和超时:可以调用XMLHttpRequest对象的abort()方法来取消正在进行的HTTP请求。调用abort()的主要原因是完成取消或超时请求超时太长或当响应变得无关时。以下提供一个兼容性比较好的实现超时的方法。
function timeoutGetText(url,timeout,callback){
var request=new XMLHttpRequest();
var timeout=false;
var timer=setTimeout(function(){
timeout=true;
request.abort();
},timeout);
request.open("GET",url);
request.onreadystatechange=function(){
if(request.readyState!==4) return;//忽略未完成的请求
if(timeout) return;//忽略终止请求
clearTimeout(timer);
if(request.status===200){//如果请求成功
callback(request.responseText);
}
}
request.send(null);//立即发送请求
}
15.使用<script>元素进行ajax传输有两个好处:1)它不受同源策略的影响,因此,可以使用它们从其他的服务器请求数据;2)包含json编码数据的响应体会自动解码(即执行)。这种使用<script>元素作为Ajax传输的技术称为JSONP(曾作为百度面试题),若HTTP请求所得到的响应数据是经过JSON编码的,则适合使用该技术。当通过<script>元素调用数据时,响应内容必须用JavaScript函数名和圆括号包裹起来。如:
handleResponse(
[1,2,{"buckle":"my shoe"}]
)
包裹后的响应会成为<script>元素的内容,它先判断JSON编码后的数据(毕竟就是一个JavaScript表达式),然后把它传递给handleResponse()函数,我们可以假设,文档拿这些数据做一些有用的事情。以下提供一个使用script元素发送JSONP请求的例子:
//根据指定的URL发送一个JSONP请求
//然后把解析得到的响应数据传递给回调函数
//在URL中添加一个名为jsonp的查询参数,用于指定该请求的回调函数的名称
function getJSONP(url,callback){
//为本次请求创建一个唯一的回调函数名称
varcbnum="cb"+getJSONP.counter++;//每次自增计数器
var cbname="getJSONP."+cbnum;//作为JSONP函数的属性
//将回调函数名称以表单编码的形式添加到URL的查询部分中
//使用jsonp作为参数名,一些支持JSONP的服务
//可能使用其他的参数名,比如callback
if(url.indexOf("?")===-1){
url+="?jsonp="+cbname;
}else{
url+="&jsonp="+cbname;
}
//创建script元素用于发送请求
varscript=document.createElement(‘script‘);
//定义被脚本执行的回调函数
getJSONP(cbnum)=function(response){
try{
callback(response);
}finally{//即使回调函数或响应抛出错误
deletegetJSONP(cbnum);//删除该函数
script.parentNode.removeChild(script);
}
};
//立即触发HTTP请求
script.src=http://www.mamicode.com/url;//设置脚本的URL
document.body.appendChild(script);
}
getJSONP.counter=0;//用于创建唯一回调函数名称的计数器
16.使用COMET来实现服务端想客户端的推送功能。
本文出自 “虎哥的博客” 博客,请务必保留此出处http://7613577.blog.51cto.com/7603577/1581777
脚本化HTTP