AJAX

第1章 AJAX

1.1 全局刷新和局部刷新

B/S 结构项目中, 浏览器(Browse)负责把用户的请求和参数通过网络发送给服务器(Server),服务端使用 Servlet(多种服务端技术的一种)接收请求,并将处理结果返回给浏览器。
浏览器在 html,jsp 上呈现数据,混合使用 css, js 帮助美化页面,或响应事件。

1.1.1 全局刷新

登录请求处理:
index.jsp 发起登录请求--------LoginServlet--------result.jsp
发起请求 request 阶段:

浏览器现在内存中是 index 页面的内容和数据 :

服务器端应答结果阶段:
 sevlet 返回后把数据全部覆盖掉原来 index 页面内容, result.jsp 覆盖了全部的浏览器内存数据。 整个浏览器数据全部被刷新。重新在浏览器窗口显示数据,样式,标签等

全局刷新原理:

1) 必须由浏览器亲自向服务端发送请求协议包。
2) 这个行为导致服务端直接将【响应包】发送到浏览器内存中
3) 这个行为导致浏览器内存中原有内容被覆盖掉
4) 这个行为导致浏览器在展示数据时候,只有响应数据可以展示

1.1.2 局部刷新

浏览器在展示数据时,此时在窗口既可以看到本次的响应数据, 同时又可以看到浏览器内存中原有数据
局部刷新原理:
1) 不能由浏览器发送请求给服务端
2) 浏览器委托浏览器内存中一个脚本对象代替浏览器发送请求.
3) 这个行为导致导致服务端直接将【响应包】发送脚本对象内存中
4) 这个行为导致脚本对象内容被覆盖掉,但是此时浏览器内存中绝大部分内容没有收到任何影响.
5) 这个行为导致浏览器在展示数据时候,同时展示原有数据和响应数据

 AJAX 实现局部刷新的一种技术。

1.2 异步请求对象:

在局部刷新,需要创建一个对象,代替浏览器发起请求的行为,这个对象存在内存中。代替浏览器发起请求并接收响应数据。这个对象叫做异步请求对象。全局刷新是同步行为, 局部刷新是异步行为[浏览器数据没有全部更新]
这个异步对象用于在后台与服务器交换数据。XMLHttpRequest 就是我们说的异步对象。
XMLHttpRequest 对象能够:
• 在不重新加载页面的情况下更新网页
• 在页面已加载后向服务器请求数据
• 在页面已加载后从服务器接收数据


所有现代浏览器 (IE7+、Firefox、Chrome、Safari 以及 Opera) 都内建了 XMLHttpRequest 对象。通过一行简单的 JavaScript 代码,我们就可以创建 XMLHttpRequest 对象
创建 XMLHttpRequest 对象的语法(xhr):

var xmlhttp = new XMLHttpRequest();

AJAX 中的核心对象就是 XMLHttpRequest

1.3 AJAX

1.3.1 什么是 AJAX

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分页面内容的新方法
AJAX 不是新的编程语言,而是使用现有技术混合使用的一种新方法。ajax 中使用的技术有JavaScript, html , dom , xml ,css 等。主要是 JavaScript , XML.
JavaScript: 使用脚本对象 XMLHttpRequest 发送请求, 接收响应数据
XML: 发送和接收的数据格式,现在使用 json
AJAX 不单需要前端的技术,同时需要后端(服务器)的配合。服务器需要提供数据,数据是 AJAX 请求的响应结果。

1.3.2 AJAX 异步实现步骤

XMLHttpRequest 对象介绍

(1) 创建对象方式

var xmlHttp = new XMLHttpRequest();

(2) onreadstatechange 事件

当请求被发送到服务器时,我们需要执行一些基于响应的任务。每当 readyState 改变时,就会触发 onreadystatechange 事件。此事件可以指定一个处理函数 function。

通过判断 XMLHttpReqeust 对象的状态,获取服务端返回的数据。
语法:

xmlHttp.onreadystatechange= function() {
 if( xmlHttp.readyState == 4 && xmlHttp.status == 200){
 处理服务器返回数据
    }
 }

下面是 XMLHttpRequest 对象的三个重要的属性:
属性说明:
onreadystatechange 属性:一个 js 函数名 或 直接定义函数,每当 readyState 属性改变时,就会调用该函数
readyState 属性:
存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
• 0: 请求未初始化,创建异步请求对象 var xmlHttp = new XMLHttpRequest()
• 1: 初始化异步请求对象, xmlHttp.open(请求方式,请求地址,true)
• 2: 异步对象发送请求, xmlHttp.send()
• 3: 异步对象接收应答数据 从服务端返回数据。XMLHttpRequest 内部处理。
• 4: 异步请求对象已经将数据解析完毕。 此时才可以读取数据。

status 属性:
200: "OK"
404: 未找到页面

(3) 初始化请求参数:

方法:

open(method,url,async) : 初始化异步请求对象

参数说明:
• method:请求的类型;GET 或 POST
• url:服务器的 servlet 地址
• async:true(异步)或 false(同步)
例如:
xmlHttp.open(“get”,”http:192.168.1.20:8080/myweb/query”,true)

(4) 发送请求

xmlHttp.send()

(5) 接收服务器响应的数据

如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或responseXML 属性。
responseText:获得字符串形式的响应数据
responseXML:获得 XML 形式的响应数据

1.4 AJAX 实例

1.4.1 全局刷新计算 bmi

需求:计算某个用户的 BMI。 用户在 jsp 输入自己的身高,体重;servlet 中计算 BMI,并显示 BMI 的计算结果和建议。
BMI 指数(即身体质量指数,英文为 BodyMassIndex,简称 BMI),是用体重公斤数除以身高米数平方得出的数字,是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准

成人的 BMI 数值:
1)过轻:低于 18.5
2)正常:18.5-23.9
3)过重:24-27
4)肥胖:28-32
5)非常肥胖,高于 32
开发步骤:

1.在 idea 中创建新的工程

名称:ch01-bmi-ajax

2.配置 tomcat 服务器

如果已经配置,省略此步骤。

选择 Local

配置 tomcat 服务器的位置

Module 添加 tomcat 支持

出现窗口

选择 2 Library

确定使用 tomcat

3.创建 jsp

定义 form,有参数 name, weight, height

4.创建 Servlet

名称 BMIServlet

public class BMIServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse
            resp)
            throws ServletException, IOException {
        String strName = req.getParameter("name");
        String strWeight = req.getParameter("weight");
        String strHeight = req.getParameter("height");
        //计算 bmi
        float weight = Float.parseFloat(strWeight);
        float height = Float.parseFloat(strHeight);
        float bmi = weight / (height * height);
        System.out.println(String.format("%s 的 bmi%s",strName,bmi));
        String msg = "";
        if( bmi < 18.5 ){
            msg = "过瘦";
        } else if( bmi >= 18.5 && bmi < 23.9 ){
            msg = "正常";
        } else if( bmi >=23.9 && bmi <= 27){
            msg = "过重";
        } else if(bmi > 27 && bmi < 32 ){
            msg = "肥胖";
        } else {
            msg="非常肥胖";
        }
        req.setAttribute("msg", strName + "你的 bmi 是"+bmi+","+msg);
        req.getRequestDispatcher("/result.jsp").forward(req,resp);
    } 
}

5.注册 servlet

6.创建 result.jsp

web 目录下创建 result.jsp 文件

7.配置运行程序

输入参数。显示 bmi

1.4.2 使用 HttpServletResponse 响应输出

1.新建 jsp

indexPrint.jsp

 2.新建 Servlet

名称 BMIServeltPrint

public class BmiAjaxServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response)
            throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("====接收了ajax的请求=====");

        //接收参数
        String strName = request.getParameter("name");
        String weight  = request.getParameter("w");
        String height = request.getParameter("h");

        //计算bmi
        float h = Float.valueOf(height);
        float w = Float.valueOf(weight);
        float bmi = w / ( h * h);

        //判断bmi的范围
        String msg = "";
        if( bmi <= 18.5) {
            msg = "您比较瘦";
        } else if( bmi > 18.5 && bmi <= 23.9 ){
            msg = "你的bmi是正常的";
        } else if( bmi >24 && bmi <=27){
            msg = "你的身体比较胖";
        } else {
            msg = "你的身体肥胖";
        }
        System.out.println("msg="+msg);
        msg = "您好:"+strName + "先生/女士, 您的bmi值是:"+ bmi + ","+ msg;

        //响应ajax需要的数据,使用HttpServletResponse输出数据
        response.setContentType("text/html;charset=utf-8");
        PrintWriter pw = response.getWriter();
        pw.println(msg);
        pw.flush();
        pw.close();
    }
}

3.注册 Servlet

1.4.3 使用 ajax 请求,计算 bmi

1.新建 ajax.jsp

2.在 ajax.jsp 的 head 部分指定 doAjax()函数

3.复制 BMIServletPrint,重新命名 BMIServletAjax

代码不需要改动

4.注册 Servlet

5.在浏览器访问 ajax.jsp

在 BMIServltAjax 的第一行设置断点,然后在 jsp 中点击按钮,发起请求,观察浏览器中的弹出的内容变化

6.修改 ajax.jsp 中的 doAjax()函数

<script type="text/javascript">
    function doAjax() {
    //创建异步对象 
    var xmlHttp = new XMLHttpRequest();
    //绑定事件 
    xmlHttp.onreadystatechange = function () {
       alert( "处理请求的状态:" + xmlHttp.readyState + "|服务器端返回数据:"+xmlHttp.responseText);
    }
    //初始化参数 
    xmlHttp.open("get","bmiAjax?name=张三&height=1.8&weight=75",true);
    //发送 ajax 异步请求
    xmlHttp.send();
 }
</script>

7.访问 ajax.jsp 请求

在 jsp 中点击按钮,发起请求,观察浏览器中的弹出的内容变化

8.获取 dom 对象 value 值

<script type="text/javascript">
     function doAjax() {
       //创建异步对象 
       var xmlHttp = new XMLHttpRequest();
       //绑定事件 
       xmlHttp.onreadystatechange = function () {
          alert( "处理请求的状态:" + xmlHttp.readyState + "|服务器端返回数据:"+xmlHttp.responseText);
       }
       //初始化参数 
       //获取页面 dom 中的数据 
       var name = document.getElementById("name").value;
       var height = document.getElementById("height").value;
       var weight = document.getElementById("weight").value;
       var param = "name="+name+"&height="+height+"&weight="+weight;
       xmlHttp.open("get","bmiAjax?"+param,true);
       //发送 ajax 异步请求 
       xmlHttp.send();
 }
</script>

9. 在浏览器测试发送 ajax 请求

10.修改 doAjax 函数

<script type="text/javascript">
 function doAjax() {
    //创建异步对象 
    var xmlHttp = new XMLHttpRequest();
    //绑定事件 
    xmlHttp.onreadystatechange = function () {
        if( xmlHttp.readyState == 4 && xmlHttp.status == 200){
            var data = xmlHttp.responseText
            document.getElementById("dataDiv").innerText = data;
        }
     }
    //初始化参数 
    //获取页面 dom 中的数据 
    var name = document.getElementById("name").value;
    var height = document.getElementById("height").value;
    var weight = document.getElementById("weight").value;
    var param = "name="+name+"&height="+height+"&weight="+weight;
    xmlHttp.open("get","bmiAjax?"+param,true);
    //发送 ajax 异步请求 
    xmlHttp.send();
 }
</script>

1.4.4 根据省份 id 查询省份名称

需求:用户在文本框架输入省份的编号 id,在其他文本框显示省份名称
项目环境准备:
1)数据库:springdb
2)数据表:
省份信息表:

SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `province`;
CREATE TABLE `province` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL COMMENT '省份名称',
  `jiancheng` varchar(255) DEFAULT NULL COMMENT '简称',
  `shenghui` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;


INSERT INTO `province` VALUES ('1', '河北', '', '石家庄');
INSERT INTO `province` VALUES ('2', '山西', '', '太原市');
INSERT INTO `province` VALUES ('3', '内蒙古', '', '呼和浩特市    ');
INSERT INTO `province` VALUES ('4', '辽宁', '', '沈阳');
INSERT INTO `province` VALUES ('5', '江苏', '', '南京');
INSERT INTO `province` VALUES ('6', '浙江', '', '杭州');
INSERT INTO `province` VALUES ('7', '安徽', '', '合肥');
INSERT INTO `province` VALUES ('8', '福建', '', '福州');
INSERT INTO `province` VALUES ('9', '江西', '', '南昌');

城市信息表:

SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `city`;
CREATE TABLE `city` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `provinceid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;


INSERT INTO `city` VALUES ('1', '石家庄市', '1');
INSERT INTO `city` VALUES ('2', '秦皇岛', '1');
INSERT INTO `city` VALUES ('3', '保定市', '1');
INSERT INTO `city` VALUES ('4', '张家口', '1');
INSERT INTO `city` VALUES ('5', '南昌市', '9');
INSERT INTO `city` VALUES ('6', '九江市', '9');
INSERT INTO `city` VALUES ('7', '宜春市', '9');
INSERT INTO `city` VALUES ('8', '福州市', '8');
INSERT INTO `city` VALUES ('9', '厦门市', '8');
INSERT INTO `city` VALUES ('10', '泉州市', '8');
INSERT INTO `city` VALUES ('11', '龙岩市', '8');
INSERT INTO `city` VALUES ('12', '太原', '2');
INSERT INTO `city` VALUES ('13', '大同', '2');
INSERT INTO `city` VALUES ('14', '呼和浩特', '3');
INSERT INTO `city` VALUES ('15', '包头', '3');
INSERT INTO `city` VALUES ('16', '呼伦贝尔', '3');

项目结构:

项目是一个 web 应用, index.jsp 发送请求, SearchServlet 接收请求, 调用 ProvinceDao
从数据库获取指定 id 的省份名称
实现步骤:

1. 在 idea 新建 web application

项目名称 ajaxweb

2. 配置 tomcat 服务器

3. 在 index.jsp 中创建 XMLHttpRequest 对象

定义表单:

4.创建 XMLHttpRequest 对象

5. 创建 Servlet 处理 Ajax 请求

6. web.xml 文件,注册 servlet

<servlet>
 <servlet-name>SearchServletservlet-name>
 <servlet-class>com.bjpowernode.controller.SearchServletservlet-class>
 servlet>
 <servlet-mapping>
 <servlet-name>SearchServletservlet-name>
 <url-pattern>/searchProvinceurl-pattern>
 servlet-mapping>

7. 发布应用到 tomcat 服务器,在浏览器访问 index.jsp,得到省份名称

 8. 添加 mysql 驱动

可以在WEB-INF目录下创 建 lib文件 , 用来存放 jar文件 , 把 准 备 好的mysql-connector-java-5.1.6.jar 拷贝到 lib 目录下。

在 Project Structure 窗口中,选择你的 modules,选择 Dependencies


确认修改:

 点击“Fix”后选择 Add lib to the artifact

9. 创建类 ProvinceDao 访问数据库

方法定义:

定义变量:

访问数据库:

finally 关闭资源

返回结果:

10. 修改之前创建的 Servlet

11. 修改 index.jsp 的 js 代码

12. 部署项目,在浏览器访问应用

 

1.4.5 使用 json 作为数据交换格式

需求:根据省份编号 id,查询省份的全部数据,数据格式 json
项目结构:

实现步骤:

1. 添加处理 json 的工具库

jackson:是非常有名的处理 json 的工具库。使用 jackson 可以实现 java 对象到 json 格式字符串的转换,也可以实现 json 字符串转为 json 对象。
把下面三个 jar 文件复制到/WEB-INF/lib 目录中。

其他步骤同 添加 mysql 驱动

2. 创建实体类 Province

3. 在 ProvinceDao 中增加方法,返回对象

方法定义:


数据库操作:

其他代码同 selectProvinceName()方法。

4. 创建新的 Servlet 对象

5. 创建 searchJson.jsp,获取 json 数据

页面定义:

AJAX 请求处理:

6. 部署应用,浏览器访问

1.4.6 异步请求

XMLHttpRequest 对象 open( method , url, true ) 第三个参数 true 表示异步请求
异步请求特点:
1)某一个时刻,浏览器可以委托多个异步请求对象发送请求,无需等待请求处理完成。
2)浏览器委托异步请求对象工作期间,浏览器处于活跃状态。可以继续向下执行其他命令。
3) 当响应就绪后再对响应结果进行处理
实现步骤:

1. 设置异步对象 open 方法第三个参数为 true

//初始请求参数
xmlHttp.open("get","searchProvinceJson?proid="+proid,true);

2. send()后面,增加 alert()

//发送请求
xmlHttp.send();
alert("我是在异步请求之后的执行代码") 

3.SearchServletJson 类的 doGet 方法第一个加入断点

4.部署应用,在浏览器访问应用。

点击“搜索”按钮,请求发送到 Servlet,程序暂停执行, js 中 alert 执行继续执行,没有等待请求处理完成,浏览器窗口弹窗“我是在异步请求之后的执行代码”字符串。

1.4.7 同步请求

XMLHttpRequest 对象 open( method , url, false ) 第三个参数 false 表示同步请求同步请求特点:


1)某一个时刻,浏览器只能委托一个异步请求对象发送请求,必须等待请求处理完成。
2)浏览器委托异步请求对象工作期间,浏览器处于等待状态。不能执行其他命令。
3)不推荐使用。


实现步骤:同 1.4.3 步骤,需要 open(method,url,false)第三个参数设为 false

1.5练习

1. 在文本框内输入省份名称中的某几个字,把符合条件的省份名称显示一个

中 2. 在文本框输入省份名称,点击按钮使用 alert 显示出这个省份的城市数量, 例如输入山西,alert 弹窗显示 3 。表示山西省在 city 表中有三个城市。

5.在浏览器访问 ajax.jsp
在 BMIServltAjax 的第一行设置断点,然后在 jsp 中点击按钮,发起请求,观察浏览器中的弹
出的内容变化
6.修改 ajax.jsp 中的 doAjax()函数

作者:王陸

-------------------------------------------

个性签名:罔谈彼短,靡持己长。做一个谦逊爱学的人!

本站使用「署名 4.0 国际」创作共享协议,转载请在文章明显位置注明作者及出处。鉴于博主处于考研复习期间,有什么问题请在评论区中提出,博主尽可能当天回复,加微信好友请注明原因

原文地址:https://www.cnblogs.com/wkfvawl/p/15084869.html