What makes AJAX-based clients unique is that the client contains page-specific control logic embedded as JavaScript technology. The page interacts with the JavaScript technology based on events such as the document being loaded, a mouse click, focus changes, or even a timer. AJAX interactions allow for a clear separation of presentation logic from the data. An HTML page can pull in bite-size pieces of data as needed rather than reloading the whole page every time a change needs to be displayed. AJAX will require a different server-side architecture to support this interaction model. Traditionally, server-side web applications have focused on generating HTML documents for every client event resulting in a call to the server. The clients would then refresh and re-render the complete HTML page for each response. Rich web applications focus on a client fetching an HTML document that acts as a template or container into which to inject content, based on client events using XML data retrieved from a server-side component.——是什么使得基于AJAX的客户端如此独特?那就是客户端所嵌入的页面特定的控制逻辑、这些控制逻辑以JavaScript代码的形式存在。页面与JavaScript的交互建立在事件的基础上(比如文档加载事件、鼠标点击事件、焦点变化事件、甚至一个时钟事件)。AJAX清楚的将表示逻辑和数据分离开来、一个HTML网页能够在需要的时候获取以比特为单位的数据片段!这不同于以前的有一点变化就必须刷新整个页面的做法。同时AJAX也需要一种完全不同的服务端架构来支持这种交互模式。以前的传统服务端WEB应用专注于为每一个客户端的每一次请求生成HTML页面、每一次客户端接到响应都要刷新和重新渲染整个页面。而我们所谈的WEB应用专注于客户端把HTML文档当作模版或容器、客户端向这个容器中插入内容、作到这些的原理就是每当客户端发生事件、客户端都可以向服务端发出请求并使用服务端返回的XML数据。Some uses for AJAX interactions are the following: 
Real-Time Form Data Validation: Form data such as user IDs, serial numbers, postal codes, or even special coupon codes that require server-side validation can be validated in a form before the user submits a form. 
Autocompletion: A specific portion of form data such as an email address, name, or city name may be autocompleted as the user types. 
Master Details Operations: Based on a client event, an HTML page can fetch more detailed information on data such as a product listing that enables the client to view the individual product information without refreshing the page. 
Sophisticated User Interface Controls: Controls such as tree controls, menus, and progress bars may be provided that do not require page refreshes. 
Refreshing Data on the Page: HTML pages may poll data from a server for up-to-date data such as scores, stock quotes, weather, or application-specific data.
——一些AJAX的使用例子如下:
    实时的表单数据验证:象ID号、序列号、邮政编码、优惠卷号码这样的表单数据可以在用户提交整个表单之前就得到验证!
    自动补全:一些特定表单数据比如email、姓名、城市名可以根据用户的类型自动填写。
    细节操作:基于客户端事件、客户可以不刷新页面就可以查看某一种产品的细节信息。
    智能客户端接口控制:诸如树、菜单、工具条都可以在不刷新页面的情况下随时提供服务。
    刷新实时数据:页面可以从服务端筛选动态数据并显示、诸如:比分、股票报价、天气预报等。
    
This list is not all-inclusive, but it shows that AJAX interactions allow web applications to do much more than they have done in the past. Although many of these benefits are noteworthy, this approach has some drawbacks as well: 
Complexity: Server-side developers will need to understand that presentation logic will be required in the HTML client pages as well as in the server-side logic to generate the XML content needed by the client HTML pages. HTML page developers must have JavaScript technology skills. Creating AJAX-enabled applications will become easier as new frameworks are created and existing frameworks evolve to support the interaction model. 
Standardization of the XMLHttpRequest Object: The XMLHttpRequest object is not yet part of the JavaScript technology specification, which means that the behavior may vary depending on the client. 
JavaScript Technology Implementations: AJAX interactions depend heavily on JavaScript technology, which has subtle differences depending on the client. See QuirksMode.org for more details on browser-specific differences. 
Debugging: AJAX applications are also difficult to debug because the processing logic is embedded both in the client and on the server. 
Viewable Source: The client-side JavaScript technology may be viewed simply by selecting View Source from an AJAX-enabled HTML page. A poorly designed AJAX-based application could open itself up to hackers or plagiarism. 
Frameworks and patterns for AJAX technology are likely to emerge as developers gain more experience writing applications that use the AJAX interaction model. It is still early to focus on a one-size-fits-all framework for AJAX interactions. This article and the associated solutions focus on how AJAX interactions can be supported today by existing Java 2 Platform, Enterprise Edition (J2EE) technologies such as servlets, JavaServer Pages (JSP) software, JavaServer Faces applications, and the Java Standard Tag Libraries (JSTL). 
——这些用处并不全、但是它们说明了AJAX交互使得WEB应用可以作到大量以前无法作到的事情。这些事情可能并不多么引人注目、而且还有一些缺陷:
    复杂性:服务端开发者必须掌握XML、页面开发者必须掌握JavaScript技术。
    XMLHttpRequest对象的标准化:XMLHttpRequest对象仍不是JavaScript标准规范。
    JavaScript技术实现:AJAX严重依赖与JavaScript技术。可参考QuirksMode.org。
    Debugging:AJAX难于调试。
    查看原文件:使用这种方法可以容易的看到JavaScript源码、给黑客、剽窃者以可乘之机。
    AJAX技术框架和模式还在探索和经验形成阶段、固化形成一个真正的框架还为时过早。本文只是探讨如何使用J2EE技术来支持AJAX交互。The Anatomy of an AJAX Interaction
Now that we have discussed what AJAX is and what some higher-level issues are, let's put all the pieces together and show an AJAX- enabled J2EE application. 
Let's consider an example. A web application contains a static HTML page, or an HTML page generated in JSP technology contains an HTML form that requires server-side logic to validate form data without refreshing the page. A server-side web component (servlet) named ValidateServlet will provide the validation logic. Figure 1 describes the details of the AJAX interaction that will provide the validation logic
——AJAX交互剖析:来看一个AJAX使能的J2EE应用:名为ValidateServlet的Servlet验证表单数据、但是要求不能对整个页面刷新。步骤如下:1、A client event occurs. ——客户端事件发生。
2、An XMLHttpRequest object is created and configured. ——一个XMLHttpRequest对象被创建并配置。
3、The XMLHttpRequest object makes a call. ——XMLHttpRequest对象发出请求。
4、The request is processed by the ValidateServlet. ——请求被ValidateServlet处理。
5、The ValidateServlet returns an XML document containing the result. ——ValidateServlet返回一个包含结果的XML文档。
6、The XMLHttpRequest object calls the callback() function and processes the result. ——XMLHttpRequest对象调用callback()函数并处理结果。
7、The HTML DOM is updated.——HTML文档对象被更新。

解决方案 »

  1.   

    各个步骤细节如下:
    1. A client event occurs.——客户端事件发生:
    点击链接或表单元素的键盘事件引发JavaScript函数validate():
    <input type="text"
                size="20"  
                  id="userid"
                name="id"
             onkeyup="validate();">2. A XMLHttpRequest object is created and configured.——一个XMLHttpRequest对象被创建并配置:
    var req;
    function validate() {
        var idField = document.getElementById("idField");
        var url = "validate?id=" + escape(idField.value);
        if (window.XMLHttpRequest) {
            req = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            req = new ActiveXObject("Microsoft.XMLHTTP");——创建XMLHttpRequest对象
        }
        req.open("GET", url, true);——调用XMLHttpRequest对象的open方法、url为所请求的服务端组件路径、true表示这个调用是异步的、如果设置为异步就必须还要有一个callback函数如下:
        req.onreadystatechange = callback;
        req.send(null);
    }3. The XMLHttpRequest object makes a call.——XMLHttpRequest对象发出请求:
    执行到req.send(null)的时候发出请求。如果是GET请求那么内容可以为空、在url附加参数。
    如果是POST请求那么就需要一个Content-Type头的设置如下:
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send("id=" + escape(idTextField.value));如果用JavaScript产生表单元素值、必须确保值编码的正确、JavaScript有一个escape()函数用于保障正确的编码、并把特定字符正确的忽略掉。4. The request is processed by the ValidateServlet.——请求被ValidateServlet所处理:
    servlet处理XMLHttpRequest就和处理其他HTTP请求一样:public class ValidateServlet extends HttpServlet {   
        private ServletContext context;
        private HashMap users = new HashMap();
        public void init(ServletConfig config) throws ServletException {
            this.context = config.getServletContext();
            users.put("greg","account data");
            users.put("duke","account data");
        }
        public void doGet(HttpServletRequest request, HttpServletResponse  response)
            throws IOException, ServletException {        String targetId = request.getParameter("id");        if ((targetId != null) && !users.containsKey(targetId.trim())) {
                response.setContentType("text/xml");
                response.setHeader("Cache-Control", "no-cache");
                response.getWriter().write("valid"); 
            } else {
                response.setContentType("text/xml");
                response.setHeader("Cache-Control", "no-cache");
                response.getWriter().write("invalid"); 
            }
        }
    }5. The ValidateServlet returns an XML document containing the results.——ValidateServlet返回一个包含结果的XML文档。
    ValidateServlet生成一个XML文档作为响应、更复杂的情况可能用到DOM、XSLT等。    response.setContentType("text/xml");
        response.setHeader("Cache-Control", "no-cache");
        response.getWriter().write("invalid"); 开发者必须了解两件事:第一:Content-Type必须设置为text/xml;第二:Cache-Control必须设置为no-cache。
      

  2.   

    6. The XMLHttpRequest object calls the callback() function and processes the result. 
    ——XMLHttpRequest对象调用callback()函数并处理结果。The XMLHttpRequest object was configured to call the callback() function when there are changes to the readyState of the XMLHttpRequest object. Let us assume the call to the ValidateServlet was made and the readyState is 4, signifying the XMLHttpRequest call is complete. The HTTP status code of 200 signifies a successful HTTP interaction. 
    ——XMLHttpRequest对象的准备状态有所变化的时候则调用callback()方法、我们假定已经请求完毕ValidateServlet、准备状态为4、表示XMLHttpRequest调用已经完成、HTTP状态码为200、表示HTTP交互已经成功。function callback() {
        if (req.readyState == 4) {
            if (req.status == 200) {
                // update the HTML DOM based on whether or not message is valid
            }
        }
    }Browsers maintain an object representation of the documents being displayed (referred to as the Document Object Model or DOM). JavaScript technology in an HTML page has access to the DOM, and APIs are available that allow JavaScript technology to modify the DOM after the page has loaded. 
    ——浏览器维护着一个文档的对象表示模型、既:DOM。网页中的JavaScript方法可以访问这个模型、并且可以在页面已经全部加载完成后再次改变这个模型。Following a successful request, JavaScript technology code may modify the DOM of the HTML page. The object representation of the XML document that was retrieved from the ValidateServlet is available to JavaScript technology code using the req.responseXML, where req is an XMLHttpRequest object. The DOM APIs provide a means for JavaScript technology to navigate the content from that document and use that content to modify the DOM of the HTML page. The string representation of the XML document that was returned may be accessed by calling req.responseText. Now let's look at how to use the DOM APIs in JavaScript technology by looking at the following XML document returned from the ValidateServlet. 
    ——使用JavaScript代码:req.responseXML可以得到服务端返回的XML文档、req为XMLHttpRequest对象、DOM为JavaScript提供了一种搜索文档内容以及根据搜索结果改变网页DOM的手段。可以使用req.responseText来访问返回的XML文档的字符串表示、如下所示: <message>
      valid
     </message>This example is a simple XML fragment that contains the sender of the message element, which is simply the string valid or invalid. A more advanced sample may contain more than one message and valid names that might be presented to the user: 
    ——上面的例子是一个简单的XML片段、实际应用可能包含更多:function parseMessage() {
        var message = req.responseXML.getElementsByTagName("message")[0];
        setMessage(message.childNodes[0].nodeValue);
    }The parseMessages() function will process an XML document retrieved from the ValidateServlet. This function will call the setMessage() with the value of the message element to update the HTML DOM. 
    ——parseMessages()方法处理从服务端返回的XML文档、该方法使用message元素的值去调用setMessage()方法来改变HTML DOM。
      

  3.   

    7. The HTML DOM is updated.——HTML文档对象被更新。JavaScript technology can gain a reference to any element in the HTML DOM using a number of APIs. The recommended way to gain a reference to an element is to call document.getElementById("userIdMessage"), where "userIdMessage" is the ID attribute of an element appearing in the HTML document. With a reference to the element, JavaScript technology may now be used to modify the element's attributes; modify the element's style properties; or add, remove, or modify child elements. 
    One common means to change the body content of an element is to set the innerHTML property on the element as in the following example. 
    ——JavaScript可以获得HTML DOM中任何元素(对象)的引用、推荐使用document.getElementById("userIdMessage")方法来获取。userIdMessage就是网页上任意元素的ID属性、有了元素(对象)的引用、JavaScript就可以改变这个元素的属性以及这个元素的样式属性、还可以增加删除或改变这个元素的子元素。通用的方法是设置innerHTML属性、如下所示:<script type="text/javascript">
     function setMessage(message) {
         var userMessageElement = document.getElementById("userIdMessage");
         userMessageElement.innerHTML = "<font color=\"red\">" + message + " </font>";
     }
    </script>
    <body>
    <div id="userIdMessage"></div>
    </body>The portions of the HTML page that were affected are re-rendered immediately following the setting of the innerHTML. If the innerHTML property contains elements such as <image> or <iframe>, the content specified by those elements is fetched and rendered as well.
    ——innerHTML属性被改变以后网页可以立即体现出变化、如果innerHTML属性内部包含象<image>、<iframe>这样的元素、那么其所指定的资源内容一样被浏览器解析显示。The main drawback with this approach is that HTML elements are hardcoded as strings in the JavaScript technology code. Hardcoding HTML up inside JavaScript technology code is not a good practice because it makes the code difficult to read, maintain, and modify. Consider using the JavaScript technology DOM APIs to create or modify HTML elements within JavaScript technology code. Intermixing presentation with JavaScript technology code as strings will make a page difficult to read and edit.
    Another means of modifying the HTML DOM is to dynamically create new elements and append them as children to a target element as in the following example. 
    ——这种方法最大的缺点是在JavaScript代码里面难于以字符串形式书写HTML、内嵌于JavaScript中的HTML也难以看懂、维护和更改。另外的改变HTML DOM的方法是动态创建新元素然后将其作为子元素插入目标元素下、如下所示:<script type="text/javascript">
     function setMessage(message) {
         var userMessageElement = document.getElementById("userIdMessage");
         var userIdMessageFont = document.getElementById("userIdMessageFont");
         var messageElement = document.createTextNode(message);
         if (userMessageElement.childNodes[0]) {
             // update the elements
             userIdMessageFont.replaceChild(messageElement, userIdMessageFont.childNodes[0]);
         } else {
             // create the new elements
             var fontElement = document.createTextNode("font");
             fontElement.setAtribute("id", "userIdMessageFont");
             fontElement.setAtribute("color", "red");
             userMessageElement.appendChild(fontElement);
             fontElement.appendChild(messageElement);
         }
     }
    </script>
    <body>
     <div id="userIdMessage"></div>
    </body>——全文完、累死了。
      

  4.   

    精简版:客户端所嵌入的页面特定的控制逻辑以JavaScript代码的形式存在。页面与JavaScript的交互建立在事件的基础上(比如文档加载事件、鼠标点击事件、焦点变化事件、甚至一个时钟事件)。AJAX清楚的将表示逻辑和数据分离开来、一个HTML网页能够在需要的时候获取以比特为单位的数据片段!这不同于以前的有一点变化就必须刷新整个页面的做法。同时AJAX也需要一种完全不同的服务端架构来支持这种交互模式。以前的传统服务端WEB应用专注于为每一个客户端的每一次请求生成HTML页面、每一次客户端接到响应都要刷新和重新渲染整个页面。而我们所谈的WEB应用专注于客户端把HTML文档当作模版或容器、客户端向其中插入内容、其原理就是每当客户端发生事件、客户端都可以向服务端发出请求并使用服务端返回的XML数据。名为ValidateServlet的Servlet验证表单数据、但是要求不能对整个页面刷新。步骤如下:1. A client event occurs.——客户端事件发生:
    点击链接或表单元素的键盘事件引发JavaScript函数validate():
    <input type="text"
                size="20"  
                  id="userid"
                name="id"
             onkeyup="validate();">2. A XMLHttpRequest object is created and configured.——一个XMLHttpRequest对象被创建并配置:
    var req;
    function validate() {
        var idField = document.getElementById("idField");
        var url = "validate?id=" + escape(idField.value);
        if (window.XMLHttpRequest) {
            req = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            req = new ActiveXObject("Microsoft.XMLHTTP");——创建XMLHttpRequest对象
        }
        req.open("GET", url, true);——调用XMLHttpRequest对象的open方法、url为所请求的服务端组件路径、true表示这个调用是异步的、如果设置为异步就必须还要有一个callback函数如下:
        req.onreadystatechange = callback;
        req.send(null);
    }3. The XMLHttpRequest object makes a call.——XMLHttpRequest对象发出请求:如果是GET请求那么内容可以为空、在url附加参数。
    如果是POST请求那么就需要一个Content-Type头的设置如下:
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send("id=" + escape(idTextField.value));如果用JavaScript产生表单元素值、必须确保值编码的正确、JavaScript有一个escape()函数用于保障正确的编码、并把特定字符正确的忽略掉。4. The request is processed by the ValidateServlet.——请求被ValidateServlet所处理:
    servlet处理XMLHttpRequest就和处理其他HTTP请求一样:public class ValidateServlet extends HttpServlet {   
        private ServletContext context;
        private HashMap users = new HashMap();
        public void init(ServletConfig config) throws ServletException {
            this.context = config.getServletContext();
            users.put("greg","account data");
            users.put("duke","account data");
        }
        public void doGet(HttpServletRequest request, HttpServletResponse  response)
            throws IOException, ServletException {        String targetId = request.getParameter("id");        if ((targetId != null) && !users.containsKey(targetId.trim())) {
                response.setContentType("text/xml");
                response.setHeader("Cache-Control", "no-cache");
                response.getWriter().write("valid"); 
            } else {
                response.setContentType("text/xml");
                response.setHeader("Cache-Control", "no-cache");
                response.getWriter().write("invalid"); 
            }
        }
    }5. The ValidateServlet returns an XML document containing the results.——ValidateServlet返回一个包含结果的XML文档。
    ValidateServlet生成一个XML文档作为响应、更复杂的情况可能用到DOM、XSLT等。    response.setContentType("text/xml");
        response.setHeader("Cache-Control", "no-cache");
        response.getWriter().write("invalid"); 
    开发者必须了解两件事:第一:Content-Type必须设置为text/xml;第二:Cache-Control必须设置为no-cache。6. The XMLHttpRequest object calls the callback() function and processes the result. 
    ——XMLHttpRequest对象调用callback()函数并处理结果。
    XMLHttpRequest对象的准备状态有所变化的时候则调用callback()方法、我们假定已经请求完毕ValidateServlet、准备状态为4、表示XMLHttpRequest调用已经完成、HTTP状态码为200、表示HTTP交互已经成功。function callback() {
        if (req.readyState == 4) {
            if (req.status == 200) {
                // update the HTML DOM based on whether or not message is valid
            }
        }
    }
    浏览器维护着一个文档的对象表示模型、既:DOM。网页中的JavaScript方法可以访问这个模型、并且可以在页面已经全部加载完成后再次改变这个模型。使用JavaScript代码:req.responseXML可以得到服务端返回的XML文档、req为XMLHttpRequest对象、DOM为JavaScript提供了一种搜索文档内容以及根据搜索结果改变网页DOM的手段。可以使用req.responseText来访问返回的XML文档的字符串表示、如下所示: <message>
      valid
     </message>上面的例子是一个简单的XML片段、实际应用可能包含更多:function parseMessage() {
        var message = req.responseXML.getElementsByTagName("message")[0];
        setMessage(message.childNodes[0].nodeValue);
    }parseMessages()方法处理从服务端返回的XML文档、该方法使用message元素的值去调用setMessage()方法来改变HTML DOM。7. The HTML DOM is updated.——HTML文档对象被更新。JavaScript可以获得HTML DOM中任何元素(对象)的引用、推荐使用document.getElementById("userIdMessage")方法来获取。userIdMessage就是网页上任意元素的ID属性、有了元素(对象)的引用、JavaScript就可以改变这个元素的属性以及这个元素的样式属性、还可以增加删除或改变这个元素的子元素。通用的方法是设置innerHTML属性、如下所示:<script type="text/javascript">
     function setMessage(message) {
         var userMessageElement = document.getElementById("userIdMessage");
         userMessageElement.innerHTML = "<font color=\"red\">" + message + " </font>";
     }
    </script>
    <body>
    <div id="userIdMessage"></div>
    </body>innerHTML属性被改变以后网页可以立即体现出变化、如果innerHTML属性内部包含象<image>、<iframe>这样的元素、那么其所指定的资源内容一样被浏览器解析显示。这种方法最大的缺点是在JavaScript代码里面难于以字符串形式书写HTML、内嵌于JavaScript中的HTML也难以看懂、维护和更改。另外的改变HTML DOM的方法是动态创建新元素然后将其作为子元素插入目标元素下、如下所示:<script type="text/javascript">
     function setMessage(message) {
         var userMessageElement = document.getElementById("userIdMessage");
         var userIdMessageFont = document.getElementById("userIdMessageFont");
         var messageElement = document.createTextNode(message);
         if (userMessageElement.childNodes[0]) {
             // update the elements
             userIdMessageFont.replaceChild(messageElement, userIdMessageFont.childNodes[0]);
         } else {
             // create the new elements
             var fontElement = document.createTextNode("font");
             fontElement.setAtribute("id", "userIdMessageFont");
             fontElement.setAtribute("color", "red");
             userMessageElement.appendChild(fontElement);
             fontElement.appendChild(messageElement);
         }
     }
    </script>
    <body>
     <div id="userIdMessage"></div>
    </body>
      

  5.   

    liushuangxian()、你头一次上网啊?没见写的开玩笑吗?
    我要是骂你一句草 你 妈你以为我会真的去草啊?
    玩不起就别玩!腻歪人、文章是不长、但是翻起来也满费劲的、至少这是SUN的权威文章、而且出处就是我、所以算准确的东西。下跪之类就是开个玩笑而已、没想到有人反映这么强烈、怪叔叔我没照顾好你们幼小稚嫩的心灵啊、乖、不哭别闹、、