`
webcode
  • 浏览: 5951377 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

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

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

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

浏览器缓存带来的问题

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工具证明这点:

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();

}

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

利用HttpWatch工具证明这点:

解决中文乱码问题

解决跨域访问问题

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

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

用户名校验实例:

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核心技术2-XMLHttpRequest对象的扩展问题

    [王兴魁]AJAX核心技术2-XMLHttpRequest对象的扩展问题

    Ajax Modifier-1.5.3.zip

    2.此扩展仅覆盖XMLHTTPRequest对象中的响应数据以及fetch方法。您可以在DevTools的&ldquo;网络&rdquo;面板中看到的原始响应不会被修改。 github:https://github.com/YGYOOO/ajax-interceptor 您可以使用该插件修改...

    AJAX-Debugger:Chrome扩展程序,它将所有AJAX(XMLHttpRequest)活动记录到开发工具控制台,允许检查AJAX调用,并在新标签页中打开调用

    AJAX调试器会将所有AJAX(XMLHttpRequest)活动记录到Chrome的开发者工具控制台。 这使开发人员可以轻松查看顶级请求信息,例如HTTP状态,响应时间和大小。 单击URL在新选项卡中打开AJAX调用,包括所有输入,从而使...

    XMLHttpRequest手册

    压缩包“ajax.rar”内含:“《掌握Ajax.chm》”和“《XMLHttpRequest手册.chm》”。 1、《掌握Ajax.chm》包含下列内容: 掌握 Ajax,第 1 部分: Ajax 入门简介 ... 掌握 Ajax,第 2 部分: 使用 JavaScript 和 Ajax ...

    Ajax课件学习(免费)

    1、XmlHttpRequest对象的open方法允许程序员用一个ajax调用向服务器发送请求。 2、method表示请求类型。最常用的有get和post请求。如果不向服务器端发送数据,只是请求服务器端的数据,这个时候可以用get方法。...

    北京中科信软AJAX培训

    XMLHttpRequest对象与Ajax XMLHttpRequest对象的属性和方法 Ajax编程 如何使用Ajax 初始化对象 指定响应处理函数 发出http请求 处理服务器返回的信息 一个初步的Ajax开发框架 异常处理机制 中文乱码问题及其解决方案...

    Ajax基础教程(扫描版)

    本书重点介绍ajax及相关的工具和技术,主要内容包括xmlhttprequest对象及其属性和方法、发送请求和处理响应、构建完备的ajax开发工具、使用jsunit测试javascript、分析javascript调试工具和技术,以及ajax开发模式和...

    Ajax完全自学手册(源代码).rar

    第3章 XMLHttpRequest对象 3.1.3 最简单的Ajax示例 第4章 DOM基础及高级DOM技术 柳州龙腾.xml XML-无限数据传输 Test4Document.htm 访问DOM对象的相关节点 Test4Document.htm 检测节点类型 Test4Attribute....

    XMLHTTPRequest:JavaScript XMLHTTPRequest对象的实现,以扩展JavaScriptCore

    尤其是JavaScriptCore并未提供AJAX请求所需的XMLHttpRequest (请参见[Mozilla文档]( )对象。该库实现了此缺少的对象,因此可以使用JavaScript库,该JavaScript库最初是为在Objective-C(或Swift)应用程序中供...

    Ajax Interceptor一个用于修改 ajax 请求响应的 chrome 扩展

    Ajax Interceptor一个用于修改 ajax 请求响应的 chrome 扩展,修改ajax请求并返回结果的ch 注意事项 不需要使用该插件直接关闭插件 安装完成后需要刷新页面 该插件修改了全局的XMLHTTPRequest对象和fetch方法里的...

    第五章-AJAX.pptx

    了解AJAX,Ajax的工作原理,AJAX包含的技术 AJAX:(Asynchronous JavaScript and XML)并不是一项新技术,其实是多种技术的...使用XMLHTTP组件XMLHttpRequest对象进行异步数据读取 使用JavaScript绑定和处理所有数据

    Ajax完全自学手册(PPT)

    第3章 XMLHttpRequest对象 3.1.3 最简单的Ajax示例 第4章 DOM基础及高级DOM技术 柳州龙腾.xml XML-无限数据传输 Test4Document.htm 访问DOM对象的相关节点 Test4Document.htm 检测节点类型 Test4Attribute....

    【卷一/共两卷】AJAX实战pdf高清版90M

    5.5.2 使用XMLHttpRequest对象 5.5.3 有效地管理用户的更新 5.6 小结 5.7 资源 第三部分 专业级的Ajax 第6章 用户体验 6.1 做正确的事:开发高质量的应用 6.1.1 响应性 6.1.2 健壮性 6.1.3 一致性 6.1.4 简单性 ...

    [ASP.NET.AJAX编程参考手册(涵盖ASP.NET.3.5及2.0)].(美)霍斯拉维.扫描版.pdf

    本书以AJAX为核心阐述对象,介绍了它对JavaScript所做的各种扩展,还介绍了在ASP.NET环境下创建客户端应用所需的一些核心控件。通过大量的实例,本书详述了AJAX的内部机制,并且紧跟时代潮流,重点描述了如何依靠...

    Ajax完全自学手册PPT和源代码(ptt格式)

    第3章 XMLHttpRequest对象 3.1.3 最简单的Ajax示例 第4章 DOM基础及高级DOM技术 柳州龙腾.xml XML-无限数据传输 Test4Document.htm 访问DOM对象的相关节点 Test4Document.htm 检测节点类型 Test4Attribute.htm 节点...

    PHP和MySQL WEB开发(第4版)

    2.10.1 使用普通文件的几个问题 2.10.2 RDBMS是如何解决这些问题的 2.11 进一步学习 2.12 下一章 第3章 使用数组 3.1 什么是数组 3.2 数字索引数组 3.2.1 数字索引数组的初始化 3.2.2 访问数组的内容 3.2.3 使用...

    PHP和MySQL Web开发第4版pdf以及源码

    2.10.1 使用普通文件的几个问题 2.10.2 RDBMS是如何解决这些问题的 2.11 进一步学习 2.12 下一章 第3章 使用数组 3.1 什么是数组 3.2 数字索引数组 3.2.1 数字索引数组的初始化 3.2.2 访问数组的内容 ...

    PHP和MySQL Web开发第4版

    2.10.1 使用普通文件的几个问题 2.10.2 RDBMS是如何解决这些问题的 2.11 进一步学习 2.12 下一章 第3章 使用数组 3.1 什么是数组 3.2 数字索引数组 3.2.1 数字索引数组的初始化 3.2.2 访问数组的内容 ...

    Ajax PHP分页演示

    今天看默默讲解分页,想想好像原创区很久没人发帖了,就顺便把默默的那个扩展开来,来个PHP+AJAX分页演示吧,好的,说来就来,首先我们依然是基本的AJAX开发框架: 复制代码 代码如下:var http_request=false;...

    javascript之AJAX框架使用说明

    框架兼容性:ajax框架的兼容性主要表现在XMLHttpRquest对象生成上。根据不同类型浏览器或者不同库一般有三种方式 new XMLHttpRequest(); new ActiveXObject(“Microsoft.XMLHTTP”); new ActiveXObject(“Msxml2....

Global site tag (gtag.js) - Google Analytics