day16_ajax学习笔记

一、什么是Ajax

Ajax( Asynchronous JavaScript And XML ):指异步 JavaScript 及 XML。
不是一种新的编程语言 ,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术,是基于JavaScript、XML、HTML、CSS的新用法。

Ajax:只刷新局部页面的技术。包括以下几种技术:

  • JavaScript:更新局部的网页。
  • XML:一般用于请求数据和响应数据的封装。
  • XMLHttpRequest对象:发送请求到服务器并获得返回结果(浏览器内核创建的)。
  • CSS:美化页面样式。
  • 异步:发送请求后不等待返回结果,由回调函数处理结果。

JavaScript 中 XMLHttpRequest 对象是整个Ajax技术的核心,它提供了异步发送请求的能力。
构造方法:


代码如下:
var xmlhttp;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp = new XMLHttpRequest();
else { // code for IE6, IE5
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

方法:
  open()  该方法有3个参数,"get|post","url?name=tom","true|false",默认为true。
  send() 发送请求,可以带参数 或 null。
  setRequestHeader() 设置请求消息头。
属性:
  readyState  类型为short,只读
  responseText  类型为String,只读
  responseXML  类型为Document,只读(一般不用)
  status  类型为short,只读
事件处理器:
  onreadystatechange

二、常用方法

  • open(method, URL, async) 建立与服务器的连接
      method参数:指请求的HTTP方法,典型的值是GET或POST
      URL参数:指请求的地址
      async参数:指是否使用异步请求,其值为true或false,默认值是true,一般这个参数不写
  • send(content) 发送请求
      content参数:指请求的参数
  • setRequestHeader(header, value) 设置请求的头信息

三、常用属性

  • onreadystatechange: 指定回调函数
  • readyState: XMLHttpRequest的状态信息(客户端:浏览器)
就绪状态码说明
0 XMLHttpRequest对象没有完成初始化,即:刚刚创建。
1 XMLHttpRequest对象开始发送请求,即:调用了open方法,但还没有调用send方法。请求还没有发出。
2 XMLHttpRequest对象的请求发送完成,即:send方法已经调用,数据已经提交到服务器,但没有任何响应。
3 XMLHttpRequest对象开始读取响应,还没有结束,即:收到了所有的响应消息头,但正文还没有完全收到。
4 XMLHttpRequest对象读取响应结束,即:一切都收到了
  • status: HTTP的状态码(服务器端)

    状态码说明
    200 服务器响应正常
    400 无法找到请求的资源
    403 没有访问权限
    500 服务器内部错误
  • responseText: 获得响应的文本内容

  • responseXML: 获得响应的XML文档对象 documednt

  注:客户端就绪状态码是4,且服务端状态码是200,才可以处理服务器数据。
示例代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/myJS.js"></script>

<title>Insert title here</title>
</head>
    <script type="text/javascript">
        // 1、获取XMLHttpRequest对象
        var req = getXMLHttpRequest();
        // 4、处理响应结果
        req.onreadystatechange = function() {
            // alert(req.readyState); // 查看客户器端就绪状态码
            if (req.readyState == 4) {
                // alert(req.status); // 查看服务器端响应状态码
                if (req.status == 200) { // 说明服务器响应一切正常
                    alert(req.responseText);
                }
            }
        }
        // 2、建立一个连接
        req.open("get""${ pageContext.request.contextPath }/servlet/servletDemo1");
        // 3、发送请求
        req.send(null);
    
</script>
<body>
</body>
</html>

代码截图如下:


使用Ajax验证用户名是否存在的实现步骤:
1、使用文本框的onblur事件(失去焦点事件)
2、使用Ajax技术实现异步交互
  a) 获取用户名
  b) 创建 XMLHttpRequest 对象
  c) 处理响应结果,创建回调函数,根据响应状态动态更新页面
  d) 建立一个连接
  e) 发送请求
示例代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<script type="text/javascript" src="${ pageContext.request.contextPath }/js/myJS.js"></script>

<title>Insert title here</title>
    <script type="text/javascript">
        function ckName() {
            // 获取用户名对象
            var name = document.getElementsByTagName("input")[0];
            // 创建XMLHttpRequest对象
            var xhr = getXMLHttpRequest();
            // 处理响应结果,创建回调函数,根据响应状态动态更新页面
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) { // 说明客户端请求一切正常
                    if (xhr.status == 200) { // 说明服务器响应一切正常
                        // alert(xhr.responseText); // 得到响应结果
                        var msg = document.getElementById("msg");
                        if (xhr.responseText == "true") {
                            // msg.innerText = "用户名已存在";
                            msg.innerHTML = "<font color='red'>该用户名已存在</font>";
                        } else {
                            msg.innerHTML = "<font color='green'>该用户名可以使用</font>";
                        }
                    }
                }
            }           
            // 建立一个连接
            xhr.open("get""${ pageContext.request.contextPath }/servlet/ckNameServlet?name=" + name.value + "&time=" + new Date().getTime());
            // 发送请求
            xhr.send(null);
        }
    
</script>
</head>
<body>
    用户名:<input type="text" name="userName" onblur="ckName()"/><span id="msg" ></span></br>
    密码:<input type="password" name="pwd" /></br>
</body>
</html>

验证用户名是否存在改进代码版本(该种方式,使得网页的标签很干净,感觉不到调用事件了):
示例代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/myJS.js"></script>

<title>Insert title here</title>
    <script type="text/javascript">
        window.onload = function() {
            var nameElement = document.getElementsByName("userName")[0];
            nameElement.onblur = function() {
                var name = this.value; // this等价于nameElement
                // 创建XMLHttpRequest对象
                var xhr = getXMLHttpRequest();
                // 处理响应结果,创建回调函数,根据响应状态动态更新页面
                xhr.onreadystatechange = function() {
                    if (xhr.readyState == 4) { // 说明客户端请求一切正常
                        if (xhr.status == 200) { // 说明服务器响应一切正常
                            // alert(xhr.responseText); // 得到响应结果
                            var msg = document.getElementById("msg");
                            if (xhr.responseText == "true") {
                                // msg.innerText = "用户名已存在";
                                msg.innerHTML = "<font color='red'>该用户名已存在</font>";
                            } else {
                                msg.innerHTML = "<font color='green'>该用户名可以使用</font>";
                            }
                        }
                    }
                }           
                // 建立一个连接
                xhr.open("get""${pageContext.request.contextPath }/servlet/ckNameServlet?name=" + name + "&time=" + new Date().getTime());
                // 发送请求
                xhr.send(null);
            }
        }
    
</script>
</head>
<body>
    用户名:<input type="text" name="userName" /><span id="msg" ></span></br>
    密码:<input type="password" name="pwd" /></br>
</body>
</html>

四、案例1:实现邮箱验证

my.js

// 获取XMLHttpRequest对象
function getXMLHttpRequest() {
    var xmlhttp;
    if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else { // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xmlhttp;
}

register.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/my.js"></script>

<head>

<title>bookStore注册页面</title>
<%--导入css --%>
<link rel="stylesheet" href="css/main.css" type="text/css" />
<script type="text/javascript">
    function changeImage() {
        document.getElementById("img").src = "${pageContext.request.contextPath}/imageCode?time="
                + new Date().getTime();
    }

    // 验证邮箱是否存在
    function ckEmail() {
        // 得到邮箱对象
        var email = document.getElementByName("email")[0];
        // 创建XMLHttpRequest对象
        var xhr = getXMLHttpRequest();
        // 处理响应结果,创建回调函数,根据响应状态动态更新页面
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    alert(xhr.responseText); // 得到响应结果
                    // 得到邮箱的font标签
                    var font = document.getElementsByTagName("font")[0];
                    if (xhr.responseText == "true") {
                        font.innerHTML = "此邮箱已被使用";
                        font.style.color = "red";
                    } else {
                        font.innerHTML = "此邮箱可以使用";
                        font.style.color = "green";
                    }
                }
            }
        }
        // 建立一个连接
        xhr.open("get""${pageContext.request.contextPath}/servlet/ckEmailServlet?email=" + email.value + "&time=" + new Date().getTime());
        // 发送请求
        xhr.send(null);
    }
</script>
</head>

<body class="main">
    <%@include file="head.jsp"%>
    <%--导入头 --%>
    <%@include file="menu_search.jsp"%><%--导入导航条与搜索 --%>

    <div id="divcontent">
        <form action="${pageContext.request.contextPath}/register.jsp"
            method="post">

            <table width="850px" border="0" cellspacing="0">
                <tr>
                    <td style="padding:30px">
                        <h1>新会员注册</h1>

                        <table width="70%" border="0" cellspacing="2" class="upline">
                            <tr>
                                <td style="text-align:right; 20%">会员邮箱:</td>
                                <td style="40%">
                                <input type="text" class="textinput"
                                    name="email" onblur="ckEmail()"/>
</td>
                                <td><font color="#999999">请输入有效的邮箱地址</font></td>
                            </tr>
.......

CkEmailServlet.java

package com.itheima.web.servlet;

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;

public class CkEmailServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException 
{

        PrintWriter out = response.getWriter();
        String email = request.getParameter("email");

        if ("tom@163.com".equals(email)) {
            out.print(true);
        } else {
            out.print(false);
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException 
{
        doGet(request, response);
    }
}

五、案例2:搜索框显示数据

1、编写显示数据的容器div
2、实现ajax响应数据
  // 创建XMLHttpRequest对象
  // 通过事件调用回调函数处理响应结果
  // 创建一个服务器连接
  // 发送请求
示例代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<script type="text/javascript"
    src="${pageContext.request.contextPath}/js/my.js">


</script>
<script type="text/javascript">
    window.onload = function() {
        // 得到搜索框对象
        var searchElement = document.getElementById("name");
        // 得到父div元素对象
        var div = document.getElementById("context1");
        // 给文件框注册按键弹起事件
        searchElement.onkeyup = function() 
            // 先获取文本框的值
            var name = this.value;

            // 如果文本框没有数据时,就把父div隐藏,且不向服务器发送请求
            if (name == "") {
                div.style.display = "none";
                return;
            }

            // 获得XMLHttpRequest对象
            var xhr = getXMLHttpRequest();
            // 处理结果
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) { // 客户端请求一 切正常
                    if (xhr.status == 200) { // 服务器响应一切正常
                        var str = xhr.responseText; // 得到服务器返回的数据
                        var ss = str.split(","); // 把字符串 1001,1002,1003 切成数组

                        var childDivs = "";
                        // 循环把数据放入子div中
                        for (var i = 0; i < ss.length; i++) {
                            childDivs += "<div onclick='writeText(this)' onmouseover='changeBackground_over(this)' onmouseout='changeBackground_out(this)'>" 
                            + ss[i] + "</div>"// 把数组中的每个元素放到子div中
                        }
                        div.innerHTML = childDivs; // 把多个子div(childDivs)放入列表父div中
                        div.style.display = "block"// 把列表隐藏
                    }
                }
            }
            xhr.open("get""${ pageContext.request.contextPath}/servlet/searchBookAJAXServlet?name=" + name + "&time=" + new Date().getTime());
            xhr.send(null);
        }
    }

    // 鼠标悬浮在子div时,改变背景色
    function changeBackground_over(div{
        div.style.backgroundColor = "gray"// backgroundColor js中属性的写法,background-color css中属性的写法
    }

    // 鼠标离开子div时,恢复背景色
    function changeBackground_out(div{
        div.style.backgroundColor = "";
    }

    // 填充文本到搜索框
    function writeText(div{
        // 先得到搜索框
        var searchElement = document.getElementById("name");
        // 把div中的文本添加到搜索框中
        searchElement.value = div.innerHTML; 
        // 把父div(context1)隐藏
        div.parentNode.style.display = "none"
    }
</script>

<div id="divmenu">
    <a href="${pageContext.request.contextPath}/showProductByPage?category=文学">文学</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=生活">生活</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=计算机">计算机</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=外语">外语</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=经营">经管</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=励志">励志</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=社科">社科</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=学术">学术</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=少儿">少儿</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=艺术">艺术</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=原版">原版</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=科技">科技</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=考试">考试</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=生活百科">生活百科</a>
    <a href="${pageContext.request.contextPath}/showProductByPage" style="color:#FFFF00">全部商品目录</a>
</div>
<div id="divsearch">
    <form action="${pageContext.request.contextPath}/findProductBySearch"
        method="post">

        <table width="100%" border="0" cellspacing="0" >
            <tr>
                <td style="text-align:right; padding-right:220px">
                Search 
                    <input type="text" name="name" class="inputtable" 
                    id="name" autocomplete="on"/>
 <!-- 解决中文提交的问题 -->
                    <input type="image" src="images/serchbutton.gif"
                    border="0" style="margin-bottom:-4px">

                </td>
            </tr>
        </table>
    </form>
</div>
    <div id="context1" style="display:block; border:1px solid red; background-color:white; 
    128px; position:absolute; left:860px; top:135px;"
>

</div>

六、json对象的学习

示例代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <script type="text/javascript">
        /* json对象有些像java的普通类对象,java是纯面向对象,javascript是基于对象和事件的脚本语言。

        // java语言创建的类
        public class Person() {
            private String name;
            private int age;

            public void show() {

            }
        }

        */


        /*

        // js语言创建的类,大小写均可,一般小写,为了更像一个类,这时我们大写
        function Person() {
            var name = "tom"; // 声明一个局部变量
            this.age = 10; // 声明一个成员变量

            this.show = function() {
                alert(name);
            }
        }

        var p = new Person();
        document.write(p.name);
        document.write(p.age);
        p.show();

        */


        var pp = [100true12.34]; // 这是一个数组
        var pp = { name:"tom"age:18
            show:function() {
                alert("hello json");
            } 
        }; // 这是一个json对象

        document.write(pp.name);
        document.write(pp.age);
        pp.show();

        var ppp = [ { name:"tom"age:18 }, { name:"lune"age:25 } ];
        document.write(ppp[1].name)

    
</script>
</body>
</html>

示例代码如下:

package com.itheima.json;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;

import com.itheima.domain.Book;
import com.itheima.util.C3P0Util;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

public class JsonTest {
    @Test // 使用 JSONObject对象封装对象数据
    public void test1() {
        Book b = new Book();
        b.setId("10001");
        b.setName("西游记");
        b.setPnum(20);

        String s = JSONObject.fromObject(b).toString();
        System.out.println(s);
    }

    @Test // 使用 JSONArray对象封装 List<Book>对象数据
    public void test2() throws SQLException {
        List<Book> list = new ArrayList<Book>();

        Book b1 = new Book();
        b1.setId("10001");
        b1.setName("西游记");
        b1.setPnum(20);

        Book b2 = new Book();
        b2.setId("10002");
        b2.setName("三国演义");
        b2.setPnum(30);

        Book b3 = new Book();
        b3.setId("10003");
        b3.setName("水浒传");
        b3.setPnum(40);

        list.add(b1);
        list.add(b2);
        list.add(b3);

        String s = JSONArray.fromObject(list).toString();
        System.out.println(s);
    }

    @Test // 使用 JSONArray对象封装 List<Book>对象数据 + 使用 JsonConfig对象过滤掉不想要的数据
    public void test3() throws SQLException {
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        List<Book> list = qr.query("select * from book"new BeanListHandler<Book>(Book.class));

        JsonConfig jc = new JsonConfig();
        jc.setExcludes(new String[]{"pnum""description""category""id"});

        String s = JSONArray.fromObject(list, jc).toString();
        System.out.println(s);
    }
}
原文地址:https://www.cnblogs.com/chenmingjun/p/9112226.html