Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

Ajax学习系列3—XMLHttpRequest对象使用的扩展问题

这次介绍使用XMLHttpRequest对象过程中,经常遇到三个问题的解决方法

Ajax学习系列2—核心对象XMLHttpRequest中介绍了XMLHttpRequest对象的五步使用法

  1. 解决浏览器缓存问题
  2. 解决中文乱码问题
  3. 解决跨域访问问题

 

浏览器缓存带来的问题

          

     Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

        AjaxCache.html

<!DOCTYPE html>
<html>
    <head>
        <title>ajax-测试缓存</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <input type="button" value="测试缓存问题" onclick="checkCache()"/>
        <div id="cacheMes"></div>

        <script type="text/javascript">
            var xmlhttp;
            function checkCache(){
                // 1.创建XMLHttpRequest对象
                if(window.XMLHttpRequest){
                    // IE7,IE8,FireFox,Mozillar,Safari,Opera
                    xmlhttp = new XMLHttpRequest();
                    // 由于Mozillar版本的,XML以MimeType开头时,服务端可能会无法工作
                    if(xmlhttp.overrideMimeType){
                        xmlhttp.overrideMimeType("text/xml");
                    }
                }else if(window.ActiveXObject){
                    // // IE5,IE5.5,IE6
                    var activexName = ["MSXML2.XMLHTTP","Miscrosoft.XMLHTTP"];
                    for(var i = 0;i < activexName.length;i++){
                        // 循环测试
                        try{
                            xmlhttp = new ActiveXObject(activeName[i]);
                            break;
                        }catch(e){};
                    }
                }else{
                    alert("不能建立XMLHttpRequest对象");
                    return false;
                }

                // 2.注册回调方法
                xmlhttp.onreadystatechange = callback; // 需要方法名
               
						/*
                // 为了屏蔽浏览器缓存,url中增加时间戳
                var url = "Cache";
                if(url.indexOf("?") > 0){
                    url = url + "&t=" + (new Date()).valueOf();
                }else{
                    url = url + "?t=" + (new Date()).valueOf();
                }
						*/                

                // 3.设置和服务端交互的基本信息(GET方式)
                xmlhttp.open("GET",url,true);
                // 4.设置向服务端发送的数据,启动和服务端的交互
                xmlhttp.send(null);
            }
              
            function callback(){
                // alert(xmlhttp.readyState);
                // 5.判断和服务端的交互是否完成,服务端是否正确返回数据,如果都正确,更新页面
                if(xmlhttp.readyState ==4){
                    // 表示交互已完成
                    if(xmlhttp.status ==200){
                        // 表示服务器的相应代码是200,正确返回数据
                        // 
                        // 纯文本数据的接受方法
                        var messageNode = document.getElementById("cacheMes");
                        messageNode.innerHTML = xmlhttp.responseText;
                        
                        // xml数据对应的dom对象接受方法
                        // 使用的前提是,服务端需要设置content-type为text/xml
                        // var domXml = xmlhttp.responseXML;
                    }
                }
            }
        </script>
    </body>
</html>

 

       Cache.java

      

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author TCH
 */
public class Cache extends HttpServlet {

    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            Integer counter = (Integer)request.getSession().getAttribute("counter");
            if(null == counter){
                counter = 0;
            }else{
                counter ++;
            }
            request.getSession().setAttribute("counter", counter);
            out.println("当前计数器的值为:" + counter);
        } finally {            
            out.close();
        }
    }

    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}

 

单击按钮多次,发现结果依然是0,达不到我们想要的结果。原因是当第二次单击按钮时,给服务端发送的和第一次发送的是相同的url,服务端回到相应的Session中查看,如果有之前访问的结果,则直接从缓存中提取数据。利用HttpWatch工具证明这点:

Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

Result列:200表示从服务端成功返回;(Cache)表示结果从缓存中返回的

URL列:两个地址相同。

 

   屏蔽缓存

   思想:善意的欺骗—让浏览器看到每次的url都不一样,也就不会到缓存中去找了。

   通过url中增加时间戳实现

   // 为了屏蔽浏览器缓存,url中增加时间戳

                var url = "Cache";

                if(url.indexOf("?") > 0){

                    url = url + "&t=" + (new Date()).valueOf();

                }else{

                    url = url + "?t=" + (new Date()).valueOf();

 

                }

 

  这次再次点击按钮,就达到了我们想要看到的效果

  Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

  利用HttpWatch工具证明这点:

Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

 

解决中文乱码问题

Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

         Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

                 Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

           Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

                  Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

 

解决跨域访问问题

Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

因为使用Ajax的跨域访问,会带来不安全因素。

 

解决:通过同域的代理,访问跨域的服务器

Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

 

用户名校验实例:

Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

AjaxProxy.html

<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <input type="text" id="userName"/>
        <input type="button" name="submit" onclick="submit()" value="AJAX校验"/>
        <div id="message"></div>

        <script type="text/javascript">
            var xmlhttp;
            function submit(){
                // 1.创建XMLHttpRequest对象
                if(window.XMLHttpRequest){
                    // IE7,IE8,FireFox,Mozillar,Safari,Opera
                    xmlhttp = new XMLHttpRequest();
                    // 由于Mozillar版本的,XML以MimeType开头时,服务端可能会无法工作
                    if(xmlhttp.overrideMimeType){
                        xmlhttp.overrideMimeType("text/xml");
                    }
                }else if(window.ActiveXObject){
                     // IE5,IE5.5,IE6
                    var activexName = ["MSXML2.XMLHTTP","Miscrosoft.XMLHTTP"];
                    for(var i = 0;i < activexName.length;i++){
                        try{
                            xmlhttp = new ActiveXObject(activeName[i]);
                            break;
                        }catch(e){};
                    }
                }else{
                    alert("不能建立XMLHttpRequest对象");
                    return false;
                }

                // 2.注册回调方法
                xmlhttp.onreadystatechange = callback; // 需要方法名
                
                var name = document.getElementById("userName").value;
                 
                // 两次编码,屏蔽请求数据中包含中文,服务端接受错误导致中文乱码问题
                name = encodeURI(encodeURI(name));
                
                // 通过代理解决跨域问题
                var url = "http://192.168.24.145:8084/VerifyUserName/AjaxServer?name=" + name;
                if(url.indexOf("http://") > 0){
                    // url = "http://192.168.24.151:8080/Ajax/AjaxServer?name="+name
                    url.replace("?","&");
                    // url = "http://192.168.24.151:8080/Ajax/AjaxServer&name="+name
                    url = "Proxy?url" + url;
                    // url = "Proxy?http://192.168.24.151:8080/Ajax/AjaxServer&name="+name
                }
                // 3.设置和服务端交互的相应参数(GET方式)
                xmlhttp.open("GET",url,true);
                // 4.设置向服务端发送的数据,启动和服务端的交互
                xmlhttp.send(null);
            }
              
            function callback(){
                // alert(xmlhttp.readyState);
                // 5.判断和服务端的交互是否完成,服务端是否正确返回数据,如果都正确,更新页面
                if(xmlhttp.readyState ==4){
                    // 表示交互已完成
                    if(xmlhttp.status ==200){
                        // 表示服务器的相应代码是200,正确返回数据
                        // 
                        // 纯文本数据的接受方法
                        var messageNode = document.getElementById("message");
                        messageNode.innerHTML = xmlhttp.responseText;
                        
                        // xml数据对应的dom对象接受方法
                        // 使用的前提是,服务端需要设置content-type为text/xml
                        // var domXml = xmlhttp.responseXML;
                    }
                }
            }
        </script>
    </body>
</html>


 

Proxy.java

 

AjaxServer.java(远程服务端)

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author TCH
 */
public class AjaxServer extends HttpServlet {

    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            String old = request.getParameter("name");
            if (old == null || old.length() == 0) {
                out.println("用户名不能为空");
            } else {
                String name = new String(old.getBytes("ISO8859-1"), "gb2312");
                if (name.equals("tch")) {
                    //4。和传统应用不同之处。这一步需要将用户感兴趣的数据返回给页面段,而不是将一个新的页面发送给用户
                    //写法没有变化,本质发生了改变
                    out.println("用户名[" + name + "]已经存在,请使用其他用户名");
                } else {
                    out.println("用户名[" + name + "]尚未存在,可以使用该用户名注册");
                }

            }
        } finally {
            out.close();
        }
    }

    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}

 

 

小结

Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

Ajax学习系列3—XMLHttpRequest对象使用的扩展有关问题

1楼tcl_6666昨天 23:45
这次够长吧!!!!!