zoukankan      html  css  js  c++  java
  • XMLHttpRequest——Ajax 时代的到来

    开发 Ajax 应用程序的难度在于,需要对 DOM、CSS 和 JavaScript 都很熟悉。

    本文目的不在于讨论如何去使用 XMLHttpRequest 对象,因为现在的 Ajax 框架很容易做到,只是从底层去看那些 Ajax 框架。像下面的代码,用 jQuery 只要一两个语句就搞定了。但这不能说明了解 XMLHttpRequest 和它的演化,一点意义都没有。

    var oXHR = new XMLHttpRequest();
    oXHR.onreadystatechange = function() {
    // TODO
    }
    oXHR.open("GET", "gAddress.txt", true);
    oXHR.send(null);

    本文内容

    • 引入
    • XMLHttpRequest 概述
    • XMLHttpRequest 演化
    • 演示:使用 XMLHttpRequest 对象获取和显示来自服务器的数据

    引入

    隐藏 iframe 技术是第一个异步模型。但它几个缺点:

    • 无法向域外的服务器发送请求。这是因为受到浏览器安全机制限制,JavaScript 只能与同一个域的表单交互,即使是来自于子域的页面也无法访问(如 p2p.wrox.com 与 www.wrox.com)。
    • 对背后所发生的 HTTP 请求缺乏足够的信息。它完全依赖于返回的正确页面。也就是说,如果隐藏帧的页面加载失败,不会向用户提示出错信息。主页面要么等待直到调用适当的 JavaScript 函数,要么设置一个较长的超时时间,最后,实在不能成功载入页面,只能显示一条信息,给用户一个安慰。

    还好,我们有另一个选择——XMLHttpRequest。可以解决隐藏帧技术存在的问题。

    XMLHttpRequest 概述

    XMLHttpRequest 解决了隐藏 iframe 技术什么问题:

    • 提供足够的 HTTP 请求信息。回想一下现在的 Ajax 框架。不仅可以访问请求和响应首部,还能访问 HTTP 状态码,这使得可以判断请求处理是否成功。

    XMLHttpRequest 也有不足之处:

    • 不像隐藏帧技术,当发出调用时,并没有浏览器的历史记录保存下来。也就是说,浏览器的后退和前进按钮无效。因此,很多 Ajax 应用程序将 XHR 和隐藏帧技术结合起来,创建一个更加可用的用户界面;
    • 如果用户将你的页面设置为特定的安全区域,该区域禁用 ActiveX 控件,这只在 IE 上,将无法访问 XHR 对象。此时,只能使用隐藏帧技术。
    • XHR 在跨域通信时也会受到限制。不过,这可以通过服务器代理解决。

    XMLHttpRequest 演化

    • 微软在 IE 5.0 引入 MSXML ActiveX 程序库,用于创建 XMLHttp 对象,使得开发人员在应用程序的任何地方初始化 HTTP 请求。微软直到 IE 7 才创建他们自己的原生 XMLHttpRequest 对象。虽然,微软的 IE 5.5/6 支持 XMLHttpRequest,但是没有这个对象的本机版本。
    • 接下来,Mozilla Firefox 也实现了 XMLHttp 功能。他们创建了一个原生的 JavaScript 对象 XMLHttpRequest。
    • 之后,Safari 1.2 和 Opera 7.6 浏览器也复制了 Mozilla 的实现。

    现在,这四种浏览器都提供了对原生 XMLHttpRequest 对象的支持。

    演示:使用 XMLHttpRequest 对象获取和显示来自服务器的数据

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>My First Ajax Script</title>
     
        <script type="text/javascript">
       1:  
       2:         window.onload = initAll;
       3:         var oXHR = false;
       4:  
       5:         function initAll() {
       6:             document.getElementById("makeTextRequest").onclick = getNewFile;
       7:             document.getElementById("makeXMLRequest").onclick = getNewFile;
       8:         }
       9:  
      10:         function getNewFile() {
      11:             makeRequest(this.href);
      12:             return false;
      13:         }
      14:  
      15:         function makeRequest(url) {
      16:             if (window.XMLHttpRequest != undefined) {
      17:                 oXHR = new XMLHttpRequest();
      18:             }
      19:             else {
      20:                 if (window.ActiveXObject) {
      21:                     var aVersions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0"];
      22:                     for (var i = 0; i < aVersions.length; i++) {
      23:                         try {
      24:                             oXHR = new ActiveXObject(aVersions[i]);
      25:                         }
      26:                         catch (e) { }
      27:                     }
      28:                 }
      29:             }
      30:  
      31:             if (oXHR) {
      32:                 oXHR.onreadystatechange = function() {
      33:                     if (oXHR.readyState == 4) {
      34:                         var outMsg;
      35:                         if (oXHR.status == 200 || oXHR.status == 304) {
      36:                             outMsg =
      37:                             (oXHR.responseXML && oXHR.responseXML.contentType == "text/xml") ? oXHR.responseXML.getElementsByTagName("choices")[0].textContent : oXHR.responseText;
      38:                         }
      39:                         else {
      40:                             outMsg = "请求发生错误...XHR 状态: " + oXHR.status;
      41:                         }
      42:                         document.getElementById("updateArea").innerHTML = outMsg;
      43:                     }
      44:                 };
      45:                 oXHR.open("GET", url, true);
      46:                 oXHR.send(null);
      47:             }
      48:             else {
      49:                 document.getElementById("updateArea").innerHTML = "不能创建一个 XMLHttpRequest 对象.";
      50:             }
      51:         }
      52:     
    </script>
     
    </head>
    <body>
        <p>
            <a id="makeTextRequest" href="gAddress.txt">请求 TXT 文件</a><br />
            <a id="makeXMLRequest" href="us-states.xml">请求 XML 文件</a></p>
        <div id="updateArea">
            &nbsp;</div>
    </body>
    </html>

    运行界面:

    5{9WJ3[C~NS)O(OBD)2[H)X

    图1 初始界面

    1YID[CKOKF)FWG1EYS[9K{L

    图2 点击“请求 TXT 文件”后

    以下几点值得说明:

    1,第 12 行,当函数返回时,告诉浏览器我们不希望装载新的页面;

    2,第 16 ~ 29 行,为兼容浏览器尝试创建 XHR 对象,看上去有点麻烦,其实你早以不必这么写。

    "oXHR = new ActiveXObject(…)" 是 IE 7 前的版本,其中,MSXML2.XMLHttp.6.0 是针对 IE 9,其他版本的 IE,微软推荐使用 3.0 版本;

    "oXHR = new XMLHttpRequest()" 支持现在所有浏览器,所以可以一直这样创建 XHR 对象。

    3,第32、44、45 行,当创建一个 XHR 对象后,总是要做三件事,或者说至少两件:

    • 设置 onreadystatechange 事件。
    • 调用 open() 创建请求。
    open(request type, URL, async)

    1)请求类型(request type):字符串。GET 或 POST。

    2)地址URL:字符串。请求的 URL。

    3)异步async:布尔型。fasle 为同步发送请求;true 为异步发送请求。也就是说,我们是否会等待。

    同步请求会让 JavaScript 等待接收到响应后再继续执行剩下代码。因此,若响应时间很长,用户在浏览器收到响应前,将无法与其交互。

    Ajax 应用程序最佳实践是,使用异步请求来实现常规数据的获取(GET 方式),使用同步请求与服务器之间发送和接收简单的消息(POST 方式)。

    如果使用同步请求,则不用设置 onreadystatechange 事件。

    • 调用 send() 发送请求。

    4,第 33 ~ 43 行,是客户端获得响应后的处理。

    • "oXHR.readyState == 4" 是所有数据都已经收到,连接已经关闭。当然还有其他状态,但是由于 的实现不同,唯一可靠的 readyState 值是4。每当 readyState 值发生变化时,就将触发 readyStateChange 事件。只判断 oXHR.readyState 是不够。
    • "oXHR.status == 200" HTTP 响应状态码,表示成功。如果状态为 304,即 "oXHR.status == 304",则 responseText 和 responseXML 属性仍然包含正确的数据。只是该数据来自于浏览器缓存,而不是服务器。

    下载 Demo

  • 相关阅读:
    三,遍历方法 1$.each(数组/对象,function处理); //$对象 调用的 2$(选择器).each(function处理); //jquery对象 调用的
    二,jquery对象 与 dom对象关系
    一,$符号的由来
    2高级js总结-------数组
    面试归来
    Http(Tcp/IP)通信建立中的三次握手
    类似于桌面启动器
    代码写Android应用的背景颜色
    靠谱的a与b互换
    day21-类的组合
  • 原文地址:https://www.cnblogs.com/liuning8023/p/2199776.html
Copyright © 2011-2022 走看看