Ajax 技术
一、Ajax 基础
1.1 什么是 Ajax?
Ajax [Asynchronous JavaScript and XML](异步 的 JavaScript 和 XML),ajax 并不是一种新型的技术,它可以做到网页刷新局部页面,而不必刷新整个网页的页面而实现某类特定的功能。
一句话来说:ajax 是只刷新局部页面的异步交互技术,它有如下特点
- ajax 并不是一种新的编程语言,它是由 JavaScript 和 XML + 异步的交互技术
- 核心对象: XMLHttpRequest (发送请求到服务器并获得返回结果)
解释一下什么是同步,什么是异步?
-
同步:我们正常访问网页的时候,都是点一个链接,页面刷新好了,就可以看到我们想看的数据
-
异步:页面向服务器发送请求之后不必等待返回结果,服务器返回的结果会由专门的回调函数来处理结果
-
回调函数【补充】:这个函数中,会检查请求的状态,如果请求的状态完成,并且没有发现服务端出现错误,那么将会从该服务器返回的数据进行处理并通常以某种形式显示输出到页面上 —— JavaScript 学习指南(第二版)
1.2 在哪里我们会用到 ajax
最常见的例子,我们在网上打开某一个在线翻译软件,比如百度翻译,我们在翻译的左侧输入内容,其实后台已经在帮我们查找我们可能要翻译的任何内容,当我们输入完毕之后,过了一会就自动显示出结果了,这就是 ajax 技术的应用,在我们没有察觉的情况下,就自动显示结果
1.3 ajax 的工作原理
Ajax 首先会向服务端发送一个请求,然后调用一个服务(回调函数),接着返回结果。这样使 客户端 和 服务端发生了少量的数据交换,ajax 实现局部页面的更新,从而减少了服务端的压力
但是为了管理服务端 和 客户端之间的异步通信,会用到一个特殊的对象,就是上面提到过的 XMLHttpRequest 对象
1.4 XMLHttpRequest 对象
1.4.1 XMLHttpRequest 常用方法
JavaScript 对象 XMLHttpRequest 是整个 Ajax 技术的核心,他提供了异步发送请求的能力,它提供了 三个常用的方法
方法名 | 说明 |
---|---|
open(method,URL,async,username,password) | 建立与服务器的链接,method参数指定请求 http的方法,最常见的是 get 请求和 post 方法, URL 参数指定请求的地址,async 参数指定是否使用异步请求,值为 true 或 false,最后两个参数 在做 htto 认证的时候会用得到 |
send(content) | 发送请求道服务器,content 参数指定请求的参数,get 请求不需要传参数,post 请求要把请求的参数写上去 |
setRequestHeader(header,value) | 设置请求头信息 |
1.4.2 XMLHttpRequest 常用属性
-
onreadystatechange:请求状态改变的事件触发器(readyState变化时会调用此方法),一般用于指定回调函数
-
readystate:XMLHttpRequest 的状态信息如下,
就绪状态码 | 说 明 |
---|---|
0 | XMLHttpRequest 对象 没有完成初始化 |
1 | XMLHttpRequest 对象 开始发送请求 |
2 | XMLHttpRequest 对象 的请求发送完成 |
3 | XMLHttpRequest 对象 读取响应 |
4 | XMLHttpRequest 对象 读取响应表结束,数据接收完成 |
- status: HTTP 的状态码
下面给大家介绍一些常见的 http 状态码,想更多了解的请移步 —— http 响应状态码大全
- 200 成功
- 400 客户端错误,404 页面不存在,403 没有权限访问
- 500 服务端发生错误
-
responseText:获取响应的内容
注意:当 readystate 为 4,而且 status 是200,才可以处理服务器响应的数据 -
responseXML:服务器返回的兼容DOM的XML内容
-
statusText:服务器返回状态码的文本信息
二、让我们来试一试吧
由于博主本科是学 Java 的,也对 java EE 比较熟悉,因此我们验证 ajax 就是用 jsp + servlet + JavaScript + ajax 来实现
2.1 简单的使用 ajax ,验证用户名是否合法
我们要实现一个简单的功能,我们注册用户名为 admin 的时候,系统会显示账号已经被注册,输入其他账号,系统可以正常运行
2.1.1 前端 demo (index.jsp)
span 标签用来显示服务端传过来的数据
<%@ 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>ajax 登录验证</title>
</head>
<body>
<form action="" method="post">
用户名:<input type="text" name="username" id="username" onblur="checkUserExit();"/><span id="info"></span><br/>
密 码:<input type="password" name="password" id="password"/></br>
<input type="submit" value="提交"/>
</form>
</body>
</html>
2.1.2 JavaScript demo (post 请求)
- 编写 onblur 事件,进行账号 非空验证
- 编写 XMLHttpRequest 对象
- 创建 http 请求
- 把文本框的内容发送给 http 请求的目标
- 指定回调函数
- 编写回调函数
- 发送 http 请求
- 将回调函数得到的内容,显示到 div 上面
这里我封装了两个函数
- checkUserExit() 账户非空验证
- doAjax(url); // 原生 ajax 应用
<script type="text/javaScript">
// onblur 触发事件,账号非空验证
function checkUserExit() {
// 我们只验证账户的合法性
var username = document.getElementById("username").value;
// 非空验证
if (username === "") {
document.getElementById("info").innerHTML = "<font color='red'>账号不能为空</font>";
return false;
} else {
document.getElementById("info").innerHTML = "<font></font>";
// 代码不非空,执行 doAjax 函数
doAjax("AjaxCheck"); // 我们使用 post 请求,传入一个 url 进去
// get 请求 'AjaxCheck?username=' + username
}
}
var xmlhttp; // 创建 XMLhttp 对象
function doAjax(url) {
// 根据不停的版本的游览器,使用不同的 ajax 的 api
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
// IE6 以下版本
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
// 绑定事件
xmlhttp.onreadystatechange = function() {
/* 使用回调函数
使用 ajax 进行处理前端界面传递过来的数据
1. 设置在服务器完成后要运行的回调函数
2. 设置请求信息
3. 发送请求
*/
if (xmlhttp.readyState == 4) { // 4 和 200 两个结果都满足才行哦
//alert(xmlhttp.readyState);
if(xmlhttp.status == 200) {
//alert(xmlhttp.status);
// responseText 表示相应请求完成后,返回服务端传过来的数据
var text = xmlhttp.responseText;
//alert(text);
// 将服务端传过来的数据打印到前端,也就是显示到 span 标签中
var msg = document.getElementById("info");
if (text === 'true') {
msg.innerHTML = "<font color='green'>可以使用</font>";
} else {
msg.innerHTML = "<font color='red'>账号已被注册!!!</font>";
}
} else {
alert("请求发回去结果有错误");
}
}
}
alert('事件绑定了');
// 创建 http 请求,建立与服务器的连接
xmlhttp.open("post", url, true); // 这里的 url 由我们从外面传进来,是 AjaxCheck (一个Servlet)
// 我们采用的 post 请求,因此需要加上请求头
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// 获取输入框 username 的值 (全局获取过了)
var username = document.getElementById("username").value;
// 发送 http 请求
xmlhttp.send("username=" + username);
}
</script>
2.1.3 JavaScript demo (get 请求)
get 请求和 post 请求的代码大体都是相同的,只有两个地方不一样
-
我们可以直接在 url 上加上我们要传递的参数:
doAjax('AjaxCheck?username='+username);
-
回调函数中,我们最后发送数据的时候,传递的参数为 null 即可:
xmlhttp.send(null);
备注:
我们使用 get 请求的时候,可以不用传递头参数
2.1.4 后端 servlet 代码
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 保证数据能够正常的响应得到
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
// 检查数据是否通过 ajax 传送过来
String username = request.getParameter("username");
// 得到数据
System.out.println("username:"+username);
// json 数据格式化,这里要用到 jsonobject 的六个包,大家自行网上下载
// JSONObject jsonobj = JSONObject.fromObject("{'username':"+username+"}");
// System.out.println(jsonobj.toString());
// 但是我这里直接接返回字符串
PrintWriter out = response.getWriter();
// 这里与前面的回调函数的内容一一对应
if (username.equals("admin")) {
out.write("false");
} else {
out.write("true");
}
}
2.2 运行截图
- 非空验证
- 账号合法验证
- 正常注册
三、学习补充
3.1 问题记录
-
在 编写 ajax 的时候,遇到了第一个 bug,那就是 前端传值为 [object, object] 各种方法百试都不灵,当我们 ajax 的 js 代码重新细化了一遍之后,数据就能正常传输了。
-
然后服务端在返回数据的时候,又出现了了问题,又是找 json 格式数据返回,xml 数据格式返回,最后是通过输出流,写入数据给 ajax 的回调函数,这样就接收到了数据
3.2 学习参考
- ajax 简介 (w3school)
- JavaScript 学习指南
3.3 更新记录
get 请求 和 post 请求示例 完善
2020年2月5日