zoukankan      html  css  js  c++  java
  • AJAX


    AJAX是 AsynchronousJavaScript + XML 的简写。 这种技术能够向服务器请求额外的数据而无须卸载页面(即刷新),会带来更好的用户体验。

    AJAX的核心为XMLHttpRequest对象(简称xhr),通过提供了向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器获取更多的信息, 这就意味着, 用户只要触发某一事件, 在不刷新网页的情况下,更新服务器最新的数据。X代表的是XML,但是用AJAX通信时数据与格式无关。

    一 创建XMLHttpRequest对象

    在很多浏览器中都可以直接创建xhr对象,但是在IE6中却还是要通过ActiveX的方式来创建xhr对象。检测浏览器支不支持直接创建方式,直接alert(typeof XMLHttpRequest),如果返回的是object则说明浏览器支持直接创建xhr对象。而IE6以及一下的浏览器中通过MSXML库来创建,可能会有三个版本。创建xhr对象的兼容方法:

    </pre><pre code_snippet_id="352182" snippet_file_name="blog_20140518_1_1513540" name="code" class="javascript"><span style="font-size:18px;">function createXhr() {
        if (typeof window.XMLHttpRequest != "undefined") {
            return new XMLHttpRequest();
        } else if (typeof ActiveXObject != "undefined") {
            var version = ["MSXML2.XMLHttp.6.0",
                            "MSXML2.XMLHttp.3.0",
                            "MSXML2.XMLHttp"];
            for (var i = 0; i < version; i++) {
                try {
                    return new ActiveXObject(version[i]);
                } catch (e) {
                }
            }
            throw new Error("您的操作系统或者浏览器不支持XHR对象");
        } else {
            throw new Error("您的操作系统或者浏览器不支持XHR对象");
        }
    }</span>



    二 使用xhr对象

    在上面创建了xhr对象以后,如果要和浏览器进行通信还必须调用两个方法:open()和send()方法。

    xhr.open(x1,x2,x3); 这个方法是用来启动一个请求,准备发送数据,三个参数:参数一是提交方式(get或者post);参数二是请求的目标页面,也就是请求的服务器处理程序页面;参数三是一个布尔值,表示同步还是异步,true表示异步请求,false表示同步请求。

    xhr.send(x1); 这个方法是真正的数据请求方法,执行这个方法后,数据请求就会提交到服务器中。接收一个参数,作为向服务器请求提供的数据主体,如果不需要则填写null即可,并且必须填写,不能够为空。

    当执行send()方法将请求发送出去,然后接到服务器的响应后,会将响应结果自动填充到xhr的属性中,xhr一共有四个属性,意义如下:

    属性 说明
    responseText 作为响应的主体返回的文本内容
    responseXML 如果响应的数据类型是“text/xml”或者“application/xml”,这返回的是XML 文档
    status 响应的HTTP状态,N个值
    statusText HTTP响应状态的说明


    属性status有很多值,代表了服务器响应的各种状态,简单的几个如下:

    状态值 状态字符串 说明
    200 OK 服务器成功的返回了数据
    400 Bad Request 语法错误,导致服务器端无法识别
    404 Not Found 指定的URL在服务器端找不到
    500 Internal Server Error 服务器端遇到无法处理的错误,占时不能够完成数据请求
    503 ServiceUnavailable  由于服务器过载或维护导致无法完成请求


    在send()方法发送完成后,就只是需要监听xhr对象的status对象的值,最好是用状态码,对于状态值在跨浏览器的时候可能不一致。如果收到的值为200,则代表服务器端正确的响应了请求。

    <span style="font-size:18px;">	//用事件注册函数给按钮btnOne添加了一个点击事件
    	addEvent(btnOne,'click',function(){
    		var xhr = createXhr();
    		xhr.open("get","one.ashx",false);	//设置为同步
    		xhr.send(null);
    		//当我们发送完成后,如果服务器有数据返回,会自动填充对象XML
    		if(xhr.status == 200){	//状态码,200表示成功返回数据,其它都是出错
    			alert(xhr.responseText);	//作为响应主体返回的文本
    			alert(xhr.responseXML);		//如果响应主体内容类型是"text/xhr"或"application/xml",则返回包含响应数据的 XML DOM 文档
    			alert(xhr.status);			//返回的HTTP状态
    			alert(xhr.statusText);		//返回的是HTTP状态说明,可能有的浏览器不一样
    		}else{
    			alert("返回数据失败:状态码:"+xhr.statue+"状态说明:"+xhr.statueText);
    		}
    	})</span>


    三 同步和异步

    在上面的xhr对象使用中采用的是同步的请求数据的方式。同步请求数据固然简单容易,但是和XML对象的请求一样,同步时会造成堵塞以及缓慢的状况。所有异步才是使用更多的方式。

    异步请求中,需要添加一个事件,readystatechange,和请求XML内容一样,这个事件中有一个属性readyState,有几个值,相比请求XML对象文档的时候多了一个:

    状态 说明
    0 未初始化 尚为调用open()方法,这个值是在open()方法调用之前会输出
    1 启动 已经调用open()方法,但是还没有调用send()方法
    2 发送 已经调用send()方法,还没有接收到数据的响应
    3 接收 已经收到部分数据的响应,还不可以使用
    4 完成 已经接收到全部的数据响应,而且可以使用


    同步请求方式:

    见上面一段代码

    异步请求方式:

    异步请求数据的时候,在readystatechange事件中,监听readyState的值,是否为4,如果为4就代表数据接收完成,然后就可以进行数据的处理,但是这个事件的方法必须要写在send()方法之前,也就是需要先注册事件。而且在send()方法调用之前还可以通过xhr.abort()方法来取消异步请求,放在send()方法之前会报出一个错误,放在 放在 responseText之前会得到一个空值。

    <span style="font-size: 18px;">	addEvent(btnTwo,"click",function(){
    	<span style="white-space:pre">	</span>var xhr = createXhr();
    		//异步中的事件,必须写在前面,状态1~4和XML中的1~4是一样的,多了一个0,表示还没有发送
    		xhr.onreadystatechange = function(){
    			if(xhr.readyState == 4){	//表示响应已经接收完成,而且可以使用数据
    				if(xhr.status == 200){	//表示服务器正确返回了页面,一切OK
    					alert(xhr.responseText);
    				}else{
    					alert("数据接收出错");
    				}
    			}else{
    			}
    		}
    		xhr.open("get","one.ashx",true);	//异步提交
    		//xhr.abort();	//用来取消请求异步提交,这个必须写在send前面,而且如果取消后会抛一个异常
    		xhr.send(null);		//必须要写在事件后面
    	})</span>


    四 GET和POST

    在提供服务器请求的过程中,有两种方式,分别是:GET 和 POST。在 Ajax 使用的过程中,GET 的使用频率要比 POST 高。

    每一次向服务器请求服务以及服务器返回服务结果的时候,都会包含一个HTTP头信息,这是浏览器和服务器自动添加的,在请求服务的时候,我们可以设置HTTP头信息,但是不能够读取,在接收到服务器的响应后,可以获取HTTP头信息,但是不能够设置HTTP头信息

    获取单个HTTP头信息的方式:xhr.getResponseHeader("Content-Type");获取HTTP响应信息中的Content-Type属性的值

    获取所有HTTP头信息的方式:xhr.getAllResponseHeaders();

    设置HTTP头信息的方式:xhr.setResquestHeader("name","value");在HTTP响应的头信息中就会添加一行:name:value,可以通过fireBug等浏览器调试工具来查看

    Get请求:

    GET 请求是最常见的请求类型,最常用于向服务器查询某些信息。必要时,可以将查询字符串参数追加到 URL 的末尾,以便提交给服务器。如果参数中存在一些特殊字符则需要通过encodeURIComponent来进行编码,Get请求的时候,参数时通过URL 后的问号给服务器传递键值对(name=value)数据,每一组数据之间用 & 来分割,服务器接收到返回响应数据,send()方法中参数值为null。

    <span style="font-size:18px;">	addEvent(btnOne,"click",function(){
    		var xhr = createXhr();
    		var url = "one.ashx?rand="+Math.random();//添加一个随机数
    		url = encodeUrl(url,"id","10002");
    		url = encodeUrl(url,"name","ab$cd");	//编码主要就是针对这种特殊字符和中文
    		xhr.onreadystatechange = function(){
    			if(xhr.readyState == 4){
    				if(xhr.status == 200){			
    					alert(xhr.responseText);
    				}else {
    					alert('获取数据错误!错误代号:' + xhr.status + ',错误信息:' + xhr.statusText);
    				}	
    			}
    		}
    		xhr.open("get",url,true);
    		xhr.send(null);
    	})
    
    	//对参数进行一个编码	
    	function encodeUrl(url,key,value){
    		url += url.indexOf('?') >=0 ? '&':'?';	//判断URL中是否包含 ? 号
    		url += encodeURIComponent(key)+"="+encodeURIComponent(value);
    		return url;
    	}</span>


    Post请求:

    Post请求可以向服务器发送很多的数据,一般在表单的提交上都用的是Post请求方式。Post请求的时候,参数不会跟在URL的后面,而是通过 & 来分割键值对,这个一个字符串整体在send(date);方法中传递给服务器。但是, 向服务器发送 POST 请求由于解析机制的原因, 需要进行特别的处理, 因为POST 请求和 Web 表单提交是不同的,需要使用 XHR 来模仿表单提交。在open()方法之后在send()方法之前需要对请求头进行一个设置,添加一句:xhr.setRequestHeader("Conent-Type","application/x-www-form-urlencoded");

    <span style="font-size:18px;">	addEvent(btnTwo,"click",function(){
    		var xhr = createXhr();
    		var url = "one.ashx?rand="+Math.random();
    		var date = "";
    		date = encodeUrl(date,"id","10021");
    		date = encodeUrl(date,"name","23%ge");
    		xhr.onreadystatechange = function(){
    			if(xhr.readyState == 4){
    				if(xhr.staus == 200){
    					alert(xhr.responseText);
    				}else{
    					alert("请求出错:状态码:"+xhr.status+" 状态说明:"+xhr.statusText);
    				}
    			}
    		}
    		xhr.open("post",url,true);
    		//Post访问需要设置头信息
    		xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    		xhr.send(date);
    	})
    <span style="white-space:pre">	</span>//编码数据
    	function encodeUrl(date,key,value){
    		date += date.length>0?'&':"";
    		date += encodeURIComponent(key);
    		date += "=";
    		date += encodeURIComponent(value);
    		return date;
    	}</span>


    从性能上面来说,GET比Post提交效率要高出很多,相同的数据量下,GET要比POST快上近两倍。

    同样,JSON格式的数据也可以通过AJAX来请求:

    <span style="font-size:18px;">	addEvent(btnThree,"click",function(){
    		var xhr = createXhr();
    		var url = "demo.json?rand"+Math.random();	//添加一个随机数,防止访问缓存的数据
    		xhr.onreadystatechange = function(){
    			if(xhr.readyState == 4){
    				if(xhr.status == 200){
    					alert(xhr.responseText);
    					var json = JSON.parse(xhr.responseText);
    					alert(json);
    				}
    			}
    		}
    		xhr.open("get",url,true);
    		xhr.send(null);
    	})</span>


    三 封装AJAX

    封装AJAX时,几个问题:参数多少;请求方式是GET还是POST,同步还是异步。为了解决上面几个方法,传递一个对象过去,这个对象中的包含了请求方式,数据(也是一个对象),同步还是异步,同时还包含一个回调函数。封装的方法是慢慢来修改而成的,不是一次形成

    回调函数:封装以后,请求数据的结果是不能够返回的,因为涉及到作用域的问题,作用域是无法返回的。故在传递的参数中,添加一个回调函数,这个回调函数接收一个参数,在封装好的AJAX方法中,当正确接收服务器端的响应数据后,调用这个回调函数,将返回的结果传递到这个回调函数中即可,这样在操作这个返回结果是在调用封装好Ajax方法

    封装Ajax:

    <span style="font-size:18px;">//封装AJAX
    function ajax(box) {
        var xhr = createXhr();
        if (box.method === "get") {
            box.url += box.url.indexOf('?') < 0 ? "?" : "&";
            box.url += getDate();
        }
        if (box.async === true) {
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    callBack();
                }
            }
        }
        xhr.open(box.method, box.url, box.async)
        if (box.method === "post") {
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhr.send(getDate());
        } else {
            xhr.send(null);
        }
        if (box.async === false) {
    		callBack();
        }
    
    	//下面俩个方法写在这个Ajax方法中,使封装更好,只是需要调用一个方法即可,但是getDate方法的使用范围就缩小了
    
        //回调方法:这里面主要是判断,数据是否正确接收,多次使用故封装起来
        function callBack() {
            if (xhr.status == 200) {
                //return xhr.responseText   返回的是为空,因为不能够返回作用域
                //通过函数的回调来实现结果的返回
                box.success(xhr.responseText);//
            } else {
                box.success("error;状态码:" + xhr.status + ";状态码解释:" + xhr.statusText);
            }
        }
        //名值对编码函数
        function getDate() {
            var arr = [];
            for (var i in box.date) {
               arr.push(encodeURIComponent(i) + "=" + encodeURIComponent(box.date[i]));
           }
           return arr.join("&");
        }
    }</span>


    调用Ajax:

    <span style="font-size:18px;">//调用
    window.onload = function () {
        var btnOne = document.getElementById("btnOne");
    	//点击按钮的时候请求数据
        btnOne.onclick = function () {
            var box = {
                method: "post",
                url: "one.ashx",
                date: {
                    "name": "abcd",
                    "age": 100
                },
                async: true,
                //用作回调函数,在这里面来操作返回的结果
                success: function (res) {
                    //alert(res);
                    //若返回的数据位JSON格式
                    var par = JSON.parse(res);
                    alert(par[0].title);
                }
            }
            ajax(box);
        }
    }</span>



  • 相关阅读:
    Atitit.Java exe bat  作为windows系统服务程序运行
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.office word  excel  ppt pdf 的web在线预览方案与html转换方案 attilax 总结
  • 原文地址:https://www.cnblogs.com/qigang/p/3841941.html
Copyright © 2011-2022 走看看