JavaWeb——AJAX(2)

使用 JavaScript 和 Ajax 发出异步请求

本章节对JavaWeb——AJAX(1)中,XMLHttpRequest对象进行详解。从创建,请求到响应的整个过程。

1、XMLHttpRequest对象简介

XMLHttpRequest对象是一个JavaScript对象,下面列出了用于该对象的几个方法和属性:

  • open(): 建立到服务器的请求
  • send(): 想服务器发送请求
  • abort(): 退出当前请求
  • readyState: 提供当前HTML的就绪状态
  • responseText: 服务器返回的请求响应文本

2、创建XMLHttpRequest对象

上一节中给出了支持多种浏览器的创建XMLHttpRequest对象的方式,代码如下所示:

    /* Create a new XMLHttpRequest object to talk to the Web server */
        var xmlHttp = false;
        /*@cc_on @*/
        /*@if (@_jscript_version >= 5)
        try {
          xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
          try {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (e2) {
            xmlHttp = false;
          }
        }
        @end @*/

        if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
          xmlHttp = new XMLHttpRequest();
        }

该段代码的核心:

  1. 建立一个变量xmlHttp来引用即将创建的XMLHttpRequest对象。
  2. 尝试在Microsoft浏览器中创建该对象(两种方式)。
  3. 如果仍然没有建立xmlHttp,则以非Microsoft的方式创建该对象。
    得到请求对象之后就可以进入请求/响应循环了。记住,XMLHttpRequest 惟一的目的是让您发送请求和接收响应。其他一切都是 JavaScript、CSS 或页面中其他代码的工作:改变用户界面、切换图像、解释服务器返回的数据。准备好 XMLHttpRequest 之后,就可以向服务器发送请求了。

此外需要注意的是,这些代码是写在<script language="javascript" type="text/javascript"> 中,即直接潜逃在script标记中。这种不放在方法或函数体中的JavaScript代码称为静态JavaScript。这是多数AJAX程序员创建XMLHttpRequest对象的一般方法。

当然我们可以把这部分代码放到函数中,例如:

    <script language="javascript" type="text/javascript">

    var request;

    function createRequest() {
      try {
        request = new XMLHttpRequest();
      } catch (trymicrosoft) {
        try {
          request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (othermicrosoft) {
          try {
            request = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (failed) {
            request = false;
          }
        }
      }

      if (!request)
        alert("Error initializing XMLHttpRequest!");
    }
    </script>

这样编写代码,我们还需要在处理AJAX之前调用这部分代码,因此还需要以下代码:

    function getCustomerInfo() {
      createRequest();
      // Do something with the request variable
    }

动态JavaScript方法的弊端是,推迟了错误通知。因为静态JavaScript保证了这些代码在用户能够与页面进行交互之前运行,而动态JavaScript,等待用户在输入文本时激活了某些ajax代码,这时如果出现不能创建XMLHttpRequest对象的问题,警告用户不能使用该应用程序,就太晚了。

因此,我们建议使用静态JavaScript的方式来实例化一个XMLHttpRequest对象。

3、 请求与响应的详细讲解

    function callServer() {
      var city = document.getElementById("city").value;
      var state = document.getElementById("state").value;
      if ((city == null) || (city == "")) return;
      if ((state == null) || (state == "")) return;
      var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);
      xmlHttp.open("GET", url, true);
      xmlHttp.onreadystatechange = updatePage;
      xmlHttp.send(null);
    }

    function updatePage() {
      if (xmlHttp.readyState == 4) {
        var response = xmlHttp.responseText;
        document.getElementById("zipCode").value = response;
      }
    }

上一节给出了请求和响应的代码,现在详细地解释一下。

3.1 建立URL

var city = document.getElementById("city").value;这一句将表单中id为city的属性值赋给了city对象。

escape()方法用于转义不能用明文正确发送的任何字符,比如空格和中文字符。

3.2 打开请求

xmlHttp.open()方法用来配置请求。该方法有五个参数:

  • request-type:发送请求的类型:GET/POST/HEAD
  • rul:要链接的URL
  • asynch:如果使用异步连接则为true
  • username:身份验证的用户名。
  • password:身份验证的口令。

3.3 发送请求

xmlHttp.send()方法用来发送请求,send只有一个参数,即要发送的内容。在GET请求中,用URL发送数据要容易,如果需要发送安全信息或者XML,则要考虑用send()传递数据。

3.4 指定回调方法

JavaScript 是一种弱类型的语言,可以用变量引用任何东西。因此如果声明了一个函数 updatePage(),JavaScript 也将该函数名看作是一个变量。换句话说,可用变量名 updatePage 在代码中引用函数。

因此,使用xmlHttp.onreadystatechange = updatePage;设置回调方法。注意,这一行代码要放在send之前设置。发送请求之前不许设置这一属性,这样服务器才能在回答完请求之后查看及触发该函数。

3.5 处理服务器响应的时机

上一节中讲到,处理响应需要注意的两点:

  • 什么也不用做,等待xmlHttp.readyState属性值为4。
  • 服务器把响应填充到xmlHttp.responseText属性中,可以从中获得。

xmlHttp.onreadystatechange = updatePage已经指定了服务器完成请求后运行的函数名,在该函数中,需要判断的第一个信息是HTTP的就绪状态——readyState属性。

HTTP就绪状态有一下五种:

  • 0:请求没有发出(在调用 open() 之前)。
  • 1:请求已经建立但还没有发出(调用 send() 之前)。
  • 2:请求已经发出正在处理之中(这里通常可以从响应得到内容头部)。
  • 3:请求已经处理,响应中通常有部分数据可用,但是服务器还没有完成响应。
  • 4:响应已完成,可以访问服务器响应并使用它。

对于AJAX编程,需要直接处理的唯一状态是就绪状态4,表示服务器响应已经完成了。

事实上,xmlHttp.onreadystatechange = updatePage这句代码,表示xmlHttp对象的readyState对象改变数值时,就会调用updatePage函数。可以在进入updatePate函数时提示当前的xmlHttp对象的readystate属性的值,来证明这一观点。

    function updatePage() {
      // Output the current ready state
      alert("updatePage() called with ready state of " + request.readyState);
    }

在浏览器中可以看到这样的提示:

readystate提示

除此之外,还需要考虑HTTP的状态码 ,我们期待的HTTP状态码是200,当然也404、403、401也很常见,我们可以加入一些这样的代码:

    if(xmlHttp.readyState == 4){
        if(xmlHttp.status == 200){
            alert("Server is done!");
        }
    }

3.6 读取响应文本

返回的数据保存在XMLHttpRequest对象的responseText属性中。在下面这个例子中,服务器返回客户的上一个订单和客户地址,中间用“|”管道符分开。

    function updatePage() {
     if (request.readyState == 4) {
       if (request.status == 200) {
         var response = request.responseText.split("|");
         document.getElementById("order").value = response[0];
         document.getElementById("address").innerHTML =
           response[1].replace(/\n/g, "");
       } else
         alert("status is " + request.status);
     }
    }

3.7 错误处理

重定向和重新路由

重定向问题是AJAX并不需要关心的问题,原因是:首先,AJAX应用程序通常都是为一个特定的服务器端脚本、servlet或应用程序而编写的;其次,AJAX应用程序和请求都是封装在沙盒中的。这就意味着提供生成Ajax请求的web页面的域必须是对这些请求都响应的域。

在HTTP状态代码中,重定向涉及到300系列的状态代码。包括:

  • 301:永久移动
  • 302:找到(请求被重新定向到另一个URL/URI上)
  • 305 :使用代理(请求必须使用一个代理来访问所请求的资源)

错误——边界情况和困难情况

错误情况出现的比率非常小,但是应用程序正常工作100次都会被忘记,一次出错就会被记住。

300系列的状态代码可以很大程度上被忽略,所需要担心的唯一一组代码就是400系列代码。就绪状态为2,3,状态代码为403,405之类的情况,我们称之为边界情况。这些边界情况是用户所碰到的问题的80%. 尽管这些问题在使用应用程序的过程中可能出现的概率只有1%. 因此,我们可以在updatePage函数中使用小的alert提醒,对错误进行处理。

function updatePage() {
     if (request.readyState == 4) {
       if (request.status == 200) {
         var response = request.responseText.split("|");
         document.getElementById("order").value = response[0];
         document.getElementById("address").innerHTML =
              response[1].replace(/\n/g, "<br />");
       } else if (request.status == 404) {
         alert ("Requested URL is not found.");
       } else if (request.status == 403) {
         alert("Access denied.");
       } else
         alert("status is " + request.status);
     }
 }

使用HEAD请求
当不确定有关脚本或服务器端组件的情况下,可以使用HEAD请求,而不是GET或者POST,不需要对响应数据真正进行处理,也不需要大量的带宽来发送响应。HEAD请求返回的是响应头信息,可以查看响应内容长度和内容类型等属性信息,基于这些可以判断响应的信息是否需要再次请求。

HEAD请求:request.open("HEAD",url,ture);
查看响应长度:request.getResponseHeader("Content-Length");
获取内容类型:request.getResponseHeader("Content-Type");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值