Ajax&jQuery

Ajax&jQuery

1.Ajax

Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新网页上的局部内容。

AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

1.1XMLHttpRequest对象

XMLHttpRequest对象用于和服务器交换数据。

  • 创建XMLHttpRequest对象
var xmlhttp;
if (window.XMLHttpRequest){
    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
    xmlhttp=new XMLHttpRequest();
}else{
    // IE6, IE5 浏览器执行代码
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

XMLHttpRequest的常用方法:

  • open(method,url,async)

    XMLHttpRequest.open(method,url,async):规定请求的类型、URL 以及是否异步处理请求。
    method:"GET":get请求;"POST":post请求
    url:"/Demo2/AjaxDemoServlet?id=1",请求地址路径
    async:true:异步请求;false:同步请求

  • send(string)

    XMLHttpRequest.send(String):将请求发送到服务器。

    ​ String仅针对post请求,get请求不能携带String。

  • setRequestHeader(header,value)

    xmlHttpRequest.setRequestHeader(header,value):向请求添加HTTP头。

    如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:

    xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlHttpRequest.send("id=1&name=wang");
    

1.2服务器响应

使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性来获取服务器的响应。

  • responseText:获得字符串形式的响应数据。
  • responseXML:获得 XML 形式的响应数据。

1.3onreadystatechange事件

用于执行一些基于响应的任务,当readyState改变时,就会触发onreadystatechange事件。

下面是 XMLHttpRequest 对象的三个重要的属性:

Ajax&jQuery

当 readyState 等于 4 且状态为 200 时,表示响应已就绪。

1.4Ajax执行Get请求

  • 不获取响应数据
<script>
      function getDemo() {
          //1.创建XMLHttpRequest对象
          var xmlHttpRequest=new XMLHttpRequest();

          //2.向服务器发送Get请求
          xmlHttpRequest.open("GET","/Demo2/AjaxDemoServlet?id=1",true);
    	  //将请求发送到服务器
          xmlHttpRequest.send();
      }
</script>
  • 获取响应数据
<script>
      function getDemo() {
          var xmlHttpRequest=new XMLHttpRequest();
          //3.注册监听,以便获取响应数据
          xmlHttpRequest.onreadystatechange=function () {         if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
                  alert(xmlHttpRequest.responseText);
              }
          }
          xmlHttpRequest.open("GET","/Demo2/AjaxDemoServlet?id=1",true);
          xmlHttpRequest.send();
      }

响应数据:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("收到一个get请求,id为"+request.getParameter("id"));
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("收到了get请求");
    }

1.5Ajax执行Post请求

  • 不获取响应数据
function postDemo() {
    	  //1.创建XMLHttpRequest对象
          var xmlHttpRequest=new XMLHttpRequest();
          //2.向服务器发送Post请求 
    xmlHttpRequest.open("POST","/Demo2/AjaxDemoServlet",true);
          //向请求添加添加http头,表示像html表单那样post数据
          xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    	 //将请求发送到服务器
          xmlHttpRequest.send("id=1&name=wang");
      }
  • 获取响应数据
 function postDemo() {
          var xmlHttpRequest=new XMLHttpRequest();
		 //获取响应数据
          xmlHttpRequest.onreadystatechange=function(){
           if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
                  alert(xmlHttpRequest.responseText);
              }
          }
          xmlHttpRequest.open("POST","/Demo2/AjaxDemoServlet",true);
          xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
          xmlHttpRequest.send("id=1&name=wang");
      }

响应数据:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("收到一个post请求,id为"+request.getParameter("id")+",name为"+request.getParameter("name"));
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("收到了post请求");
    }

1.6案例:Ajax校验用户名是否可用

  • register_Ajax.jsp
<head>
    <title>用户注册页面</title>
    <script>
        function checkUsername() {
            var xmlHttpRequest=new XMLHttpRequest();
            var username=document.getElementById("name").value;
            xmlHttpRequest.onreadystatechange=function () {
                if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
                    var data=xmlHttpRequest.responseText;
                    if(data==0){
                        document.getElementById("span1").innerHTML="<font color='red'>用户名已被占用</font>"
                    }else if(data==1){
                        document.getElementById("span1").innerHTML="<font color='green'>用户名可用</font>"
                    }
                }
            }
            xmlHttpRequest.open("GET","/Demo2/CheckUsernameServlet?username="+username,true);
            xmlHttpRequest.send();
        }
    </script>
</head>
<body>
    <form action="RegisterServlet" method="post">
        请输入用户名:<input type="text" name="username" ></span><br/>
        请输入密码:<input type="text" name="password"/><br/>
        <input type="submit" value="注册"/>
    </form>
</body>

注意:获取id为name的元素的值要用document.getElementById("name").value,而不是document.getElementById("name")。

用document.getElementById("name")获取的是元素,而不是值,如下图:

Ajax&jQuery

  • CheckUsernameServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        response.setContentType("text/html;charset=utf-8");
        if(username.equals("COCO")){
           // response.getWriter().write(0);
            response.getWriter().print(0);
        }else {
            //response.getWriter().write(1);
            response.getWriter().print(1);
        }
    }

注意:这里返回int只能用print或println,write只能写字符型,即char,而且数字传到前端会产生乱码,如下:

Ajax&jQuery

  • write和print方法比较:

write():仅支持输出字符类型数据,字符、字符数组、字符串等;
print():可以将各种类型(包括Object)的数据通过默认编码转换成bytes字节形式,这些字节都通过write(int c)方法被输出。

2.jQuery

jQuery是一个JavaScript库,可以极大简化Javascript编程。

2.1安装jQuery

  • 下载后安装jQuery

将jquery-1.11.3.min.js拷贝到工程目录中,如web/js/jquery-1.11.3.min.js,然后在页面上引用:

<script src="js/jquery-1.11.3.min.js"></script>
是否疑惑为什么没有在 <script> 标签中使用 type="text/javascript"?因为在HTML5中,不必那样做了。JavaScript 是HTML5以及所有现代浏览器中的默认脚本语言。
  • CDN引用

如果不希望下载并存放 jQuery,那么也可以通过 CDN(内容分发网络) 引用它。Staticfile CDN、百度、又拍云、新浪、谷歌和微软的服务器都存有 jQuery 。

百度CDN:

<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">

又拍云CDN:

<script src="https://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js">

2.2jQuery选择器

  • 元素选择器

    基于元素名选取元素。

    $("button"):在页面获取所有的<button>元素。

  • id选择器

    通过元素的id属性选取指定的元素。

    $("#id2"):获取id为id2的元素。

  • 类选择器

    通过指定的class属性查找元素。

    $(".test"):查找带有class="test"属性的元素。

2.3jQuery设置内容

  • text()

    设置或返回所选元素的文本内容,两个标签中写值,如<textarea ></textarea>

  • html()

    设置或返回元素的内容(包括html标记)。

  • val()

    设置或返回表单字段的值,用于元素里面有value属性的。

2.4jQuery常用方法

2.4.1load()方法

load()方法从服务器加载数据,并把返回的数据放入被选元素中。

语法:

$(selector).load(URL,data,callback);
/*
必需的 URL 参数规定您希望加载的 URL。
可选的 data 参数规定与请求一同发送的查询字符串键/值对集合。
可选的 callback 参数是 load() 方法完成后所执行的函数名称。
*/
2.4.1.1load()方法演示
  • jQueryServlet
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("收到一个请求");
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("执行load方法");
    }
  • jQueryDemo.jsp
<head>
    <title>Title</title>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        function loadDemo() {
            $("#id2").load("/Demo2/jQueryServlet",function (responseTxt,statusTxt,xhr){
                $("#id2").val(responseTxt);//将响应回的数据放入到id为id2的元素中
            });
        }
    </script>
</head>
<body>
    <a href="" onclick="loadDemo()" >使用jQuery执行load方法</a><br/>
    <input type="button" value="使用jQuery执行load方法" onclick="loadDemo()"/>
    <input type="text" />
</body>

注意:

如果用超链接:

<a href="" onclick="loadDemo()" >使用jQuery执行load方法</a><br/>

响应回的数据会在id2中一闪而过,原因是有两次刷新,先走 onClick的方法,取到数据回来之后,赋值显示。接着走 href=""的路径,但是这个属性没有给值,所以会把当前的页面重新再刷新一次,导致看不见值。

2.4.2get()方法

$.get() 方法通过 HTTP GET 请求从服务器上请求数据。

语法:

$.get(url,callback);

必需的url参数规定希望请求的URL。

可选的callback参数是请求成功后所执行的函数名。

2.4.2.1get()方法演示
    <script>
        $(document).ready(function () {
            $("button").click(function () {//即点击button后执行get请求
                $.get("/Demo2/jQueryServlet",function (data,status) {
                    $("#id2").val(data);//将返回的数据填入id2
                    $("#id3").text(data);
                });
            });
        })
    </script>
<body>
    <button>演示get</button><br/>
    <input type="text" />
    <textarea ></textarea>
</body>

2.4.3post()方法

$.post() 方法通过 HTTP POST 请求从服务器上请求数据。

语法:

$.post(url,data,callback);

必需的url参数规定您希望请求的url。

可选的data参数规定连同请求发送的数据。

可选的callback参数是请求成功后所执行的函数名。

2.4.3.1post()方法演示
<script>
    $(document).ready(function () {
                $("button").click(function () {
                    $.post("/Demo2/jQueryServlet",{name:"wanger",age:19},
                           function (data,status) {
                       		 $("#id2").val(data+"\"+status);
                   		 });
                });
    })
</script>	
<body>
    <button>演示post</button><br/>
	<input type="text" />
</body>

2.5案例1:jQuery校验用户名是否可用

  • register_jQuery.jsp
    <script>
        function checkUsername() {
            //var username=document.getElementById("name").value;
            var username=$("#name").val();//以jQuery方式获取用户名
            $.post("/Demo2/jQueryServlet",{name:username},function (data,status) {
                if(data==0){
                    $("#span1").html("<font color='red'>用户名已被占用</font>");
                }else{
                    $("#span1").html("<font color='green'>用户名可用</font>");
                }
            })
        }
    </script>
<body>
    <form action="RegisterServlet" method="post">
        请输入用户名:<input type="text" name="username" ></span><br/>
        请输入密码:<input type="text" name="password"/><br/>
        <input type="submit" value="注册"/>
    </form>
</body>

2.6案例2:jQuery实现仿百度提示

效果如下:

Ajax&jQuery

  • HeimaSearch.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>黑马搜索</title>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        /*文档就绪代码:$(document).ready(function () {})可简写为$(function(){})*/
        $(function () {
            $("#search").keyup(function () {
                //var search=$("#search").val();
                var search=$(this).val();//this即为执行此方法的对象:$("#search");
                if(search!=""){//当输入框不为空时才发送请求
                    $.post("/StuSysMvc/HeimaSearchServlet",{searchValue:search},function(data,status){
                        if(data!=""){
                            $("#div01").show();//当返回值不为空时才展示搜索提示框
                            $("#div01").html(data);
                        }else{
                            $("#div01").hide();//非第一次时返回值为空时隐藏搜索提示框
                        }
                    })
                }else{
                    $("#div01").hide();//删除搜索内容后要隐藏搜索提示框
                }
            })
        })
    </script>
</head>
<body>
    <center >
        <br/><br/><br/><br/><br/><br/>
        <h2>Heima黑马</h2>
        <input type="text" name="search" />
        <input type="button" value="黑马一下"  style="height: 55px ;  100px ; ">
        <div ></div>
        <%--
    		display:none搜索框默认不显示;
    		div01这个div不指定高度,而是根据返回的list.jsp中的数据动态调整。
        --%>
    </center>
</body>
</html>
  • HeimaSearchServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String searchValue = request.getParameter("searchValue");
        System.out.println("收到请求:"+searchValue);
        StudentService studentService=new StudentServiceImpl();
        List<Student> list=studentService.initSearch(searchValue);//dao层可设置默认最多只查找10条
        request.setAttribute("list",list);
        request.getRequestDispatcher("list.jsp").forward(request,response);
        //响应list.jsp页面给请求者。请求:浏览器请求,浏览器看到这个jsp页面
    }
  • list.jsp

    在list.jsp页面遍历list,HeimaSearchServlet将list.jsp返回给请求者。

<table width="100%"><%--设置此table和div同宽,使结果左对齐--%>
    <c:forEach var="stu" items="${list}">
        <tr>
            <td>${stu.sname}</td>
        </tr>
    </c:forEach>
</table>

2.7案例3:jQuery实现省市联动

2.7.1数据库准备

准备两张表:province和city,给city表的c_pid字段添加外键约束指向province表的唯一索引:主键pid。

Ajax&jQuery

2.7.2使用xml传输数据

  • 依赖jar包

    Ajax&jQuery

  • proCity_xml.jsp

<script>
        $(function () {
            $("#province").change(function () {
                var choice=$(this).val();
                if(choice!=""){
                    $.post("/StuSysMvc/ProCityServlet",{province:choice},function (data,status) {
                        $("#city").html("<option value=''>--请选择--</option>");//清空city中的option
                        //从data数据里找出所有的city,然后遍历所有的city,每遍历一个city就执行一次function方法
                        /*<list>
                            <city>
                                <cid>1<id>
                                <cname>郑州</cname>
                                <cPid>1</cPid>
                            </city>
                            ......
                        </list>*/
                        $(data).find("city").each(function () {
                            var cid=$(this).children("cid").text();
                            var cname=$(this).children("cname").text();
                            $("#city").append("<option value='"+cid+"'>"+cname+"</option>");
                        })
                    })
                }
            });
        });
    </script>
</head>
<body>
    省份:<select name="province" >
            <option value="">--请选择--</option>
            <option value="1">河南</option>
            <option value="2">广东</option>
         </select>
    城市:<select name="city" >
            <option value="">--请选择--</option>
         </select>
</body>
  • ProCityServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer pid = Integer.parseInt(request.getParameter("province"));
        StudentService studentService=new StudentServiceImpl();
        List<City> list = studentService.findCityByPid(pid);
        //返回数据
        //可以像仿百度提示那样返回html,但最好采用返回xml或json
        //1.返回xml
        XStream xStream=new XStream();
        //xStream.useAttributeFor(City.class,"cid");//将cid设置为city的属性,写在设置别名前后均可
        xStream.alias("city",City.class);
        //xStream.useAttributeFor(City.class,"cid");
        String s = xStream.toXML(list);
        response.setContentType("text/xml;charset=utf-8");//注意这里是xml
        response.getWriter().write(s);
    }

xml数据如下:

Ajax&jQuery

修改别名:将com.itheima.entity.City改为city,并将cid设置为city的属性:

Ajax&jQuery

2.7.3使用json传输数据

  • 依赖jar包:

    Ajax&jQuery

  • proCity_json.jsp

    <script>
        $(function () {
            $("#province").change(function () {
                var choice=$(this).val();
                if(choice!=""){
                    $.post("/StuSysMvc/ProCityServlet",{province:choice},function (data,status) {
                        $("#city").html("<option value=''>--请选择--</option>");
                        /*data:
                        [
                            {
                                "cPid":2,
                                "cid":5,
                                "cname":"广州"
                            },
                           ...
                        ]
                         */
                        //先遍历,再追加
                        $(data).each(function (index,c) {//index:索引;c:遍历到的元素
                            $("#city").append("<option value='"+c.cid+"'>"+c.cname+"</option>")
                        })
                    },"json")//最后一个参数为dataType,指定数据类型为json,默认智能判断(xml,json,script,html),但json数据不能识别出来,需要声明一下
                }
            });
        });
    </script>
  • ProCityServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer pid = Integer.parseInt(request.getParameter("province"));
        StudentService studentService=new StudentServiceImpl();
        List<City> list = studentService.findCityByPid(pid);
        //返回数据
        //2.返回Json
        JSONArray jsonArray = JSONArray.fromObject(list);
        /*
        JSONArray:转化为json数组:[{"cPid":2,"cid":5,"cname":"广州"},{"cPid":2,"cid":6,"cname":"东莞"},{"cPid":2,"cid":7,"cname":"深圳"},{"cPid":2,"cid":8,"cname":"江门"}]
        JSONObject:转化为接送数据:{"cPid":2,"cid":5,"cname":"广州"}
         */
        String s = jsonArray.toString();
        System.out.println(s);
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(s);*/
    }