高级程序设计——Ajax

来源:互联网 发布:逆袭的感受知乎 编辑:程序博客网 时间:2024/05/05 10:13

  • 一前言
  • 二XMLHttpRequest对象
    • XHR的用法
    • HTTP头部信息
    • GET请求
    • POST请求
  • 三XMLHttpRequest 2级
    • FormData
    • 超时设定
    • overrideMimeType方法
  • 四进度事件
    • load事件
    • progress事件

一、前言

  1. 这一技术能够向服务器请求额外的数据而无须卸载页面,会带来更好的用户体验。

  2. Ajax这一技术的核心是XMLHttpRequest对象(简称XHR)

  3. XHR为向服务器发送请求和解析服务器相应提供了流畅的接口。能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。也就是说,可以使用XHR对象取得新数据,然后 再通过DOM将新数据插入到页面中。

  4. 虽然名字中包含XML的成分,但Ajax通信与数据格式无关;这种技术就是无需刷新即可从服务器取得数据,但不一定是XML数据。

二、XMLHttpRequest对象

  1. 浏览器差异导致在IE中可能会遇到三种不同版本的XHR对象

  2. 现在的浏览器大都支持原生的XHR对象

    function createXHR(){    if(typeof XMLHttpRequest !="undefined"){        //创建XHR对象        return new XMLHttpRequest();    }    else if(typeof ActiveXObject!="undefined"){        //适用于IE7之前的版本        if(typeof arguments.callee.activeXString !="string"){            var versions=["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],i,len;            for(i=0,len=versions.length;i<len;i++){                try{                    new ActiveXObject(versions[i]);                    arguments.callee.activeXString=versions[i];                    break;                }catch(ex){                    //跳过                }            }        }            return new ActiveXObject(arguments.callee.activeXString);    }    else{        throw new Error("no xhr object available");    }}

XHR的用法

  1. 在使用XHR对象时,要调用的第一个方法是open(),它接受3个参数

    • 要发送的请求的类型:get、post等
    • 请求的url
    • 表示是否异步发送请求的布尔值
      xhr.open("get","example.php",false);
    • 调用open()方法并不会真正发送请求,而只是启动一个请求以备发送
    • 只能向同一个域中使用相同端口和协议的URL发送请求
  2. send()方法

    • 一个参数:要作为请求主体发送的数据;如果不需要通过请求主体发送数据,则必须传入null
    • 调用该方法后,请求就会被分派到服务器
  3. 在收到响应后,相应的数据会自动填充XHR对象的属性
    • responseText:作为响应主体被返回的文本,无论内容类型是什么
    • responseXML:
      • 如果响应的内容类型是”text/xml”或”application/xml”,这个属性中将保存包含着响应数据的XML DOM文档
      • 对于非XML数据,属性值为null
    • status:响应的HTTP状态
      • 200:成功的标志。此时,responseText属性的内容已经就绪,而且在内容类型正确的情况下,responseXML也应该能够访问了。
      • 304:请求的资源并没有被修改,可以直接使用浏览器中缓存的版本。也意味着响应是有效的。
    • statusText:HTTP状态的说明
  4. readyState属性:表示请求/响应过程的当前活动阶段
    • 0:未初始化。尚未open()
    • 1:启动。调用open()
    • 2:发送。调用send()
    • 3:接收。已经接收到部分响应数据
    • 4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了
  5. 只要上述属性的值发生改变,就会触发一次readystatechange事件。必须在调用open()之前指定onreadtstatechange事件处理程序才能确保跨浏览器兼容性。

  6. 上述事件处理程序,不建议使用this对象。如果使用,在有的浏览器中会导致函数执行失败,或者导致错误发生。因此,使用实际的xhr对象实例变量是较为可靠的一种方式。

  7. 在接收到响应之前还可以调用abort()方法来取消异步请求。之后xhr对象会停止触发事件,而且也不再允许访问任何与响应有关的对象属性。在终止请求之后,还应该对XHR对象进行解引用操作。且不建议重用xhr对象。
    xhr.abort();

    var xhr=createXHR();xhr.onreadystatechange=function(){    if(xhr.readyState==4){        if(xhr.status>=200&&xhr.status<300||xhr.status==304){            alert(xhr.reasponseText);        }        else{            alert("unsuccessful:"+xhr.status);        }    }};xhr.open("get","example.txt",true);xhr.send(null);

HTTP头部信息

  1. 每个HTTP请求和响应都会带有相应的头部信息。

  2. 默认情况下,在发送xhr请求的同时,还会发送下列头部信息:

    • Accept:在浏览器能够处理的内容类型
    • Accept-Charset:浏览器能够显示的字符集
    • Accept-Encoding:浏览器能够处理的压缩编码
    • Accept-Language:浏览器当前设置的语言
    • Connection:浏览器与服务器之间连接的类型
    • Cookie:当前页面设置的任何Cookie
    • Host:发出请求的页面所在的域
    • Referer:发出请求的页面的URI
    • User-Agent:浏览器的用户代理字符串
  3. 使用setRequestHeader()方法,可以设置自定义的请求头部信息。两个参数

    • 头部字段的名称
    • 头部字段的值
    • 在open()之后,send()之前调用
    xhr.open("get","example.php","true");xhr.setRequestHeader("MyHeader","MyValue");xhr.send(null);
    • 服务器在接收到这种自定义的头部信息后,可以执行相应的后续操作
    • 建议使用自定义的头部字段名称,否则有可能会影响服务器的响应
  4. 调用xhr对象的getResponseHeader()方法
    • 传入头部字段名称
    • 取得相应的响应头部信息
  5. 调用getAllResponseHeaders()方法,可以取得一个包含所有头部信息的长字符串

GET请求

  1. 最常用于向服务器查询某些信息,可以将查询字符串参数追加到URL的末尾,以便将信息发送给服务器。

  2. 对XHR而言,位于传入open()方法的URL末尾的查询字符串必须经过正确的编码才行。

  3. 使用encodeURICompinent()进行编码,然后才能放到URL的末尾;而且所有名值对都必须由和号(&)分隔

    var url="example.php";function addURLParam(url,name,value){    url+=(url.indexOf("?")==-1?"?":"&");    url+=encodeURIComonent(name)+"="+encodeURIComponent(value);    return url;}//添加参数url=addURLParam(url,"name","Mary");//初始化请求xhr.open("get",url,false);

POST请求

  1. 通常用于向服务器发送应该被保存的数据。

  2. POST请求的主题可以包含非常多的数据,而且格式不限。

  3. 第一步,初始化一个POST请求
    xhr.open("post","example.php",true);

  4. 第二步,向send()方法中传入某些数据。可以传入XML DOM文档,传入的文档经序列化之后将作为请求主体被提交到服务器;也可以传入任何想发送到服务器的字符串

  5. 服务器对POST请求和提交web表单的请求不会一视同仁。因此,服务器端必须有程序来读取发送过来的原始数据。不过,可以使用XHR来模仿表单提交:

    • 将Content-Type头部信息设置为application/x-www-form-urlencoded,也就是表单提交时的内容类型
    • 以适当的格式创建一个字符串
    //把表单中的数据序列化之后发送给服务器xhr.open("post","example.php",true);xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");var form=document.getElementById("user-info");xhr.send(serialize(form));

三、XMLHttpRequest 2级

FormData

  1. FormData为序列化表单以及创建与表单格式相同的数据(用于通过xhr传输)提供了便利

  2. 创建后可以添加数据,通过append()方法:

    • 接收两个参数:键和值
    • 分别对应表单字段的名字和字段中包含的值
    • 可以添加任意多个
  3. 通过向FormData构造函数中传入表单元素,也可以用表单元素的数据预先向其中填入键值对

    var data=new FormData(document.forms[0]);data.append("name","mary");
  4. 创建了实例后,可以将它直接传给XHR的send()方法
    xhr.send(new FormData(form));

  5. 优点:不必设置请求头部,xhr对象能够识别传入的数据类型是FormData的实例,并配置适当的头部信息

超时设定

  1. timeout属性:在给其设置一个数值后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发timeout事件,进而会调用ontimeout事件处理程序。仅适用于ie8+

    xhr.open("get","timeout.php",true);xhr.timeout(1000);//1秒钟xhr.ontimeout=function(){    alert("request did not return in a second.");};xhr.send(null);

overrideMimeType()方法

  1. 用于重写XHR响应的MIME类型
  2. 必须在send()方法前调用,才能保证重写响应的MIME类型
    xhr.overrideMimeType("texe/xml");

四、进度事件

  1. 与客户端服务器通信有关的事件
    • loadstart:在接收到响应数据的第一个字节时触发
    • progress:在接收响应期间持续不断地触发
    • error:在请求发生错误时触发
    • abort:在因为调用abort()方法而终止连接时触发
    • load:在接收到完整的响应数据时触发
    • loadend:在通信完成或者触发load、error、或abort事件后触发
  2. 每个请求都从loadstart事件开始,接下来是一或多个progress事件,然后触发error、abort或load事件中的一个,最后以触发loadend事件结束

load事件

  1. 不必检查readystate属性了,但是要检查status属性
  2. event对象浏览器有差异性,所以还是要使用xhr对象变量

progress事件

  1. 事件处理程序会接收到一个event对象,其target属性是xhr对象,包含三个额外的属性:
    • lengthComputable:表示进度信息是否可用的布尔值
    • position:表示已经接收的字节数
    • totalSize:表示根据Content-Length响应头部确定的预期字节数
  2. 在open()方法之前调用onprogress事件处理程序

    xhr.onprogress=function(event){    var divstatus=document.getElementById("status");    if(event.lengthComputable){        divstatus.innerHTML="recived"+event.position+"of"+event.totalSize+"bytes";    }};xhr.open("get","example.php",true);xhr.send(null);
原创粉丝点击