• JavaScript入门之AJAX:原生ajax


    背景

          传统的Web应用允许用户端填写表单(form),当提交表单时就向网页服务器发送一个请求。服务器接收并处理传来的表单,然后送回一个新的网页,但这个做法浪费了许多带宽,因为在前后两个页面中的大部分HTML码往往是相同的。由于每次应用的沟通都需要向服务器发送请求,应用的回应时间依赖于服务器的回应时间。这导致了用户界面的回应比本机应用慢得多。

          2005年2月18号,一位大佬,名叫Jesse James Garrett(杰西·詹姆斯·贾瑞特),发表了一篇文章叫做“Ajax: A new Approach to Web Applications”,介绍了一种技术叫做Asynchronous JavaScript and XML,这项技术能够向服务器请求额外的数据而不需要重新加载页面,这样就可以部分请求数据而不需要刷新整个页面,不仅仅节约了大量的带宽,还加快了响应速度。

    --摘自维基百科并稍作修改

    XHR

          XHR全称是XMLHttpRequest,可扩展超文本传输请求,是一个API,它通过URL在客户端和服务器端传输数据而不需要使页面刷新,提供了对 HTTP 协议的完全的访问,是AJAX技术的核心对象,AJAX的请求过程可以据此分为四个部分:

    1 创建 XMLHttpRequest 对象
    2 连接后台服务器
    3 发送数据请求
    4 接收服务器的响应数据;

          XHR对象在IE5中第一次引入,对象是通过MSXML库中的一个ActiveX对象实现的。因而IE中可能遇到三种不同版本的XHR对象:MSXML2.XMLHttp、MSXML2.XMLHttp.3.0、MSXML2.XMLHttp.6.0。IE7+、Firefox、Opera、Chrome 和Safari 都支持原生的XHR 对象。

    一、创建XMLHttpRequest 对象

          如果要兼容IE7之前的浏览器的话,要根据不同的XHR版本来编写函数,再创建ActiveXObject对象,而其他的浏览器,则可以直接创建 XMLHttpRequest 对象。代码如下:

     1 function createXHR(){
     2     if (typeof XMLHttpRequest != "undefined"){
     3         return new XMLHttpRequest();
     4     } else if (typeof ActiveXObject != "undefined"){
     5         if (typeof arguments.callee.activeXString != "string"){
     6             var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
     7                     "MSXML2.XMLHttp"],
     8                 i, len;
     9             for (i=0,len=versions.length; i < len; i++){
    10                 try {
    11                     new ActiveXObject(versions[i]);
    12                     arguments.callee.activeXString = versions[i];
    13                     break;
    14                 } catch (ex){
    15                     //跳过
    16                 }
    17             }
    18         }
    19         return new ActiveXObject(arguments.callee.activeXString);
    20     } else {
    21         throw new Error("No XHR object available.");
    22     }
    23 }
    24 var xhr = createXHR();

          不过现在一般很少人想要兼容IE7之前的版本了,于是可以简化如下:

    var xhr = new XMLHttpRequest();

    二、连接服务器与发送数据

          XMLHttpRequest连接服务器也不难:

    xhr.open(method, url, async, user, password)

          使用以上的open方法来初始化一个请求即可,open方法的参数说明如下:

    method:
    请求所使用的HTTP方法; 例如 "GET", "POST", "PUT", "DELETE"等. 如果下个参数是非HTTP(S)的URL,则忽略该参数.
    
    url:
    该请求所要访问的URL
    
    async:
    一个可选的布尔值参数,默认为true,意味着是否执行异步操作,如果值为false,则send()方法不会返回任何东西,直到接受到了服务器的返回数据。如果为值为true,一个对开发者透明的通知会发送到相关的事件监听者。这个值必须是true,如果multipart 属性是true,否则将会出现一个意外。
    
    user:
    用户名,可选参数,为授权使用;默认参数为空string.
    
    password:
    密码,可选参数,为授权使用;默认参数为空string.

           method方法中最常用的请求类型便是GET和POST,一般情况下:

    1、GET用于向服务器查询某些信息,而POST向服务器发送要保存的数据。
    
    2、GET将查询字符串参数追加到URL的末尾发给服务器,而POST通过传递参数给send()方法发送数据。

          举个栗子:

    1      if ( method == "GET") {
    2             xhr.open("GET",url + "?" + params, true);
    3             xhr.send(null);
    4         } else if ( method == "POST") {
    5             xhr.open("POST", url, true);
    6             //设置表单提交时的内容类型
    7             xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    8             xhr.send(params);
    9         }

          如上所示,GET请求是直接在URL后面添加 ?+parm_name=parm_value&……来传递数据,然后xhr.send(null)(注:null不能省略)

    http://www.yourhost.com?username="myname"&password="123"

    而POST请求则是模拟表单提交,将头部信息设置为表单提交时的内容类型,然后将params当做send()方法的参数传递给服务器。

    三、接收服务器的响应数据

          在调用send()方法后,请求便会派发到服务器,服务器对请求进行处理后作出响应。然后自动填充到XHR对象的属性中。

    responseText:作为响应主体被返回的文本。
    responseXML:如果响应的内容类型是"text/xml"或"application/xml",这个属性中将保存包含着响应数据的XML DOM 文档。
    status:响应的HTTP 状态。
    statusText:HTTP 状态的说明。

          我们根据检测XHR对象中的 readyState 属性,可以获取当前的响应状态:

    0:未初始化。尚未调用open()方法。
    1:启动。已经调用open()方法,但尚未调用send()方法。
    2:发送。已经调用send()方法,但尚未接收到响应。
    3:接收。已经接收到部分响应数据。
    4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。

          一般而言,我们只对状态“4”感兴趣,而 readyState 每次更改,都会触发一次readystatechange监听事件,因此,我们可以通过在监听函数中判断 readyState 的来判断响应是否成功,并取得响应数据。

    xhr.onreadystatechange = function(){
        if (xhr.readyState == 4){
            //200-300表示成功返回,304表示资源未修改
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                //在这里对响应数据进行处理(保存、打印等)
                console.log(xhr.responseText);
            } else {
                alert("Request was unsuccessful: " + xhr.status);
            }
        }
    };

    至此,一次完整的AJAX请求就已经完成了:

     1 //创建
     2 var xhr = createXHR();
     3 //监听状态、处理数据
     4 xhr.onreadystatechange = function(){
     5     if (xhr.readyState == 4){
     6         if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
     7             //对xhr.responseText响应数据进行处理;
     8         } else {
     9             alert("Request was unsuccessful: " + xhr.status);
    10         }
    11     }
    12 };
    13 //连接
    14 xhr.open("get", "/xxx/xxx?param1=value1&param2=value2", true);
    15 //发送
    16 xhr.send(null);
    17 
    18 function createXHR(){
    19     if (typeof XMLHttpRequest != "undefined"){
    20         return new XMLHttpRequest();
    21     } else if (typeof ActiveXObject != "undefined"){
    22         if (typeof arguments.callee.activeXString != "string"){
    23             var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
    24                     "MSXML2.XMLHttp"],
    25                 i, len;
    26             for (i=0,len=versions.length; i < len; i++){
    27                 try {
    28                     new ActiveXObject(versions[i]);
    29                     arguments.callee.activeXString = versions[i];
    30                     break;
    31                 } catch (ex){
    32                 }
    33             }
    34         }
    35         return new ActiveXObject(arguments.callee.activeXString);
    36     } else {
    37         throw new Error("No XHR object available.");
    38     }
    39 }

    参考资料:

    1、XMLHttpRequest-MDN

    2、《JavaScript高级程序设计(第三版)》

  • 相关阅读:
    Java编程语言学习01-Java语言概述
    Java复习面试指南-06为什么要进行数据类型转换?什么情况下会进行自动类型转换?
    Java复习面试指南-05简单说一下Java当中的char字符类型?
    Java复习面试指南-04Java语言支持的8种基本数据类型是什么?占用的空间是多少?
    Java复习面试指南03-说一下Java当中标识符与关键字的区别?
    Linq LeftJoin 取不同和想同的对像
    vue父组件异步传递prop到子组件echarts画图问题踩坑总结
    linux下使用openssl生成https的crt和key证书
    css hover延时 解决快速划入划出
    记录时间操作
  • 原文地址:https://www.cnblogs.com/ljwTiey/p/7405834.html
Copyright © 2020-2023  润新知