脚本化HTTP

  1. AjaxAsynchronousJavaScript and XML:异步JavascriptXMLajax描述了一种主要使用脚本操纵HTTPWeb应用架构。其主要特点是:使用脚本操纵HTTPWeb服务器进行数据交换,不会导致页面重载。

  2. <iframe>元素更加强大,为了把<iframe>作为ajax传输协议使用,脚本首先要发送给Web服务器的信息编码到URL中,然后设置<Iframe>src属性为该URL。服务器能够创建个包含响应内容的HTML文档,并把它返回Web服务器,并且在<iframe>中显示它。脚本通过遍历<iframe>的文档对象来读取服务端的响应。注意:这受限于同源策略。

  3. <script>元素的src属性设置URL并发起HTTP GET请求。使用<script>元素实现脚本操纵HTTP是非常吸引人的,因为他们可以跨域通信而不受限于同源策略。通常,使用基于<script>Ajax传输协议时,服务器的响应采用Json编码的数据格式,当执行脚本时,JavaScript解析器能自动将其“解码”。由于使用JSON数据格式,因此这种Ajax传输协议也叫做“JSONP”。

  4. IE5IE6不支持XMLHttpRequest对象,不过它支持一个ActiveX对象,以下提供一个在IE5IE6中模拟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部分组成:1HTTP请求方法或“动作”(verb);2)正在请求的URL3)一个可选的请求头集合,其中可能包括身份验证信息;4)一个可选的请求主体。服务器返回的HTTP响应包含3部分:1)一个数字和文字组成的状态码,用来显示请求的成功或失败;2)一个响应头集合;3)响应主体。

6.HTTP请求的各部分有指定顺序:请求方法和URL首先到达,然后是请求头,最后是请求主体。XMLHttpRequest实现通常直到调用send方法才开始启动网络。但XMLHttpRequest API的设计似乎使每个方法都将写入网络流。这意味着调用XMLHttpRequest方法的顺序必须匹配HTTP请求的架构。例如,setRequestHeader()方法的调用必须在调用open()之后但在调用send()之前,否则它将抛出异常。

7.一个完整的HTTP响应由状态码、响应头集合和响应主体组成。这些都可以通过XMLHttpRequest对象的属性和方法使用:

    1)  statusstatusText属性以数字和文本的形式返回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改变为01时,可能没有触发这个事件。当调用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=data[name].toString();

       name=encodeURIComponent(name.replace("%20","+"));

        value=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规范草案定义了更多有用的事件集,有已经在FirefoxChromeSafari中得到支持。在这个新的事件模型中,XMLHttpRequest对象在请求的不同阶段触发不同类型的事件,所以它不再需要检查readyState属性。在支持它们的浏览器中,这些新事件会像如下这样触发。当正在加载服务器的响应时,XMLHttpRequest对象会发生progress事件,通常每个50秒左右,所以可以使用这些事件给用户反馈请求进度。如果请求快速完成,他们可能从不会触发progress事件。当事件完成时,会触发load事件。

HTTP请求无法完成有三种情况,对应3种事件。如果请求超时,会触发timeout事件。如果请求终止,会触发abort事件。最后像太多重定向这样的网络错误会阻止请求的完成,但这些情况会触发error事件。如果正常完成则触发load事件。

只要以上中的一个触发,浏览器就会触发loadend事件。

progress事件相关联的事件对象还有3个有用的属性。loaded属性时目前传输的字节数值。total属性自“Content-Length”头传输的数据的整体长度(单位是字节),如果不知道内容长度则为0。最后,如果知道内容长度则lengthComputable属性为true,否则为false。显然,totalloaded属性对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=url;//设置脚本的URL

   document.body.appendChild(script);

}

getJSONP.counter=0;//用于创建唯一回调函数名称的计数器

16.使用COMET来实现服务端想客户端的推送功能。


本文出自 “虎哥的博客” 博客,请务必保留此出处http://7613577.blog.51cto.com/7603577/1581777

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。