3.传统表单提交交互和Ajax交互的区别
4.Ajax使用详解
5.实战案例
5.1 验证用户名
5.2级联效果
6.总结
<div id="link01"></div>
1. 概念
-
Ajax:(Asynchronous JavaScript And XML)指异步 JavaScript 及 XML
-
他不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术,是基于JavaScript、XML、HTML、CSS新用法
-
Ajax指的是刷新局部页面的技术
同步和异步的区别
同步:客户端必须等待服务器端的响应。在等待的期间客户端不能做其他操作。
异步:客户端不需要等待服务器端的响应。在服务器处理请求的过程中,客户端可以进行其他的操作。
<div id="link02"></div>
2、应用场景
搜索
地图
校验
获取数据
<div id="link03"></div>
3、传统表单提交交互和Ajax交互的区别
-
传统模式下,表单提交则整个页面重绘,为了维持页面用户对表单的状态改变,要多些不少代码。要在控制器和模板之间传递更多参数以保持页面状态。而AJAX不然,因为页面只是局部更新, 不关心也不会影响页面其他部分的内容。
-
Ajax在提交、请求、接收时,都是异步进行的,网页不需要刷新;Form提交则是新建一个页面,哪怕是提交给自己本身的页面,也是需要刷新的;
-
Ajax在提交时,是在后台新建一个请求;Form却是放弃本页面,而后再请求;
-
Ajax必须要使用JS来实现,不启用JS的浏览器,无法完成该操作;Form却是浏览器的本能,无论是否开启JS,都可以提交表单;
-
Ajax在提交、请求、接收时,整个过程都需要使用程序来对其数据进行处理;
-
Ajax提交时,却是根据你的表单结构自动完成,不需要代码干预。
<div id="link04"></div>
4.Ajax使用详解
4.1 XMLHttpRequest对象
-
该对象用于在前台与服务器交换数据。意味着可以在不重新加载整个网页的情况下,对网页的进行局部更新
-
所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)
//获取XMLHttpRequest对象,
function getXMLHttpRequest() {
var xmlHttp;
if (window.XMLHttpRequest) {// 新浏览器
xmlHttp = new XMLHttpRequest();
}else if (window. ActiveXObject) {// IE6及以下浏览器
xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP");
}
return xmlHttp;
}
4.2 与服务器交换数据 open/send
如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send()
open(method,url,async); | 初始化请求参数(请求方式,请求地址,是否异步) | xmlhttp.open("GET","url",true); |
---|---|---|
send(); | 发送请求 | xmlhttp.sen的(); |
//发送异步的Post请求
function sendAjaxPost() {
var xmlHttp = getXMLHttpRequest();
//初始化请求参数
xmlHttp.open("POST","MyServlet",true);
//post需要设置请求头
xmlHttp.setRequestHeader(
"Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
//发送请求,携带数据
xmlHttp.send("username=abc&password=123");
}
//发送异步的Get请求
function sendAjaxGet() {
var xmlHttp = getXMLHttpRequest();
//初始化请求参数
xmlHttp.open("GET","MyServlet?username=abc&password=123",true);
//发送请求,携带数据
xmlHttp.send();
}
4.3 onreadystatechange事件
请求被发送到服务器时,我们需要执行一些基于响应的任务
函数 | 描述 |
---|---|
onreadystatechange | 每当 readyState 属性改变时,就会调用该函数。 |
属性 | 描述 |
---|---|
readyState | 存有 XMLHttpRequest 的状态。 从 0 到 4 发生变化: 0 - 请求未初始化服务器 1 - 连接已建立 2 - 请求已接收 3 - 请求处理中 4 - 请求已完成,且响应已就绪 |
status | 存有响应的状态。 200 - OK 404 - 未找到页面 |
//发送异步的Post请求
function sendAjaxPost() {
var xmlHttp = getXMLHttpRequest();
//每当readyState改变时,就会触发 onreadystatechange事件
xmlHttp.onreadystatechange = function() {
console.log(xmlHttp.readyState);//打印XMLHttpRequest的状态
console.log(xmlHttp.status + "xx");//打印响应的状态
}
xmlHttp.open("POST","MyServlet",true);
xmlHttp.setRequestHeader(
"Content-Type","application/x-www-form-urlencoded;charset-UTF-8");
xmlHttp.send("username=abc&password=123");
}
<div id="link05"></div>
5、实战案例
5、1 验证用户名
验证用户名的是否可以注册
html页面代码
<body>
<h1>注册页面</h1>
<form action="RegisterServlet" method="post">
账号:<input name="username" type="text" placeholder="请输入账号..."
onblur="validateUsername(this)"/><font></font><br/>
密码:<input name="password" type="password" placeholder="请输入密码..."/><br/>
<input type="submit" value="注册"/>
</form>
<script type="text/javascript">
var font = document.getElementsByTagName("font")[0];
function validateUsername(obj) {
var xmlHttp = getXMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
//获取来自响应的信息
var text = xmlHttp.responseText;
if(text == "1"){
font.color = "red";
font.innerText = "抱歉,账号已被注册";
}else if(text == "0"){
font.color = "green";
font.innerText = "恭喜,账号可用";
}
}
}
xmlHttp.open("POST","MyServlet",true);
xmlHttp.setRequestHeader(
"Content-Type","application/x-www-form-urlencoded;charset-UTF-8");
xmlHttp.send("username="+obj.value);
}
function getXMLHttpRequest() {
var xmlHttp;
if (window.XMLHttpRequest) {// 新浏览器
xmlHttp = new XMLHttpRequest();
}else if (window. ActiveXObject) {// IE6及以下浏览器
xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP");
}
return xmlHttp;
}
</script>
</body>
Java代码
public class MyServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String username = request.getParameter("username");
if(username.equals("hhy")){//已有此用户名
response.getWriter().write("1");
}else{//未有此用户名
response.getWriter().write("0");
}
}
}
<div id="link06"></div>
5.2 级联效果
通过选择省从而关联出城市的数据
前端发送Ajax异步请求到服务器中获取对应的省市JSON数据,再在前端解析、适配到页面
-
添加数据库
-
导入数据库驱动包、Druid连接池
-
添加省、市实体类
-
添加数据库工具类
-
编写数据持久层
-
编写Servlet
-
编写前端页面
1.省份实体类 |
public class Province{
private int id;//id
private String code;//省份编号
private String name;//省份名
public Province() {
}
public Province(int id, String code, String name) {
this.id = id;
this.code = code;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Province [id=" + id + ", code=" + code + ", name=" + name + "]";
}
}
2.城市实体类
public class City{
private int id;//id
private String code;//城市编号
private String name;//城市名
private String parentCode;//所属省份编号
public City() {
}
public City(int id, String code, String name, String parentCode) {
this.id = id;
this.code = code;
this.name = name;
this.parentCode = parentCode;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParentCode() {
return parentCode;
}
public void setParentCode(String parentCode) {
this.parentCode = parentCode;
}
@Override
public String toString() {
return "City [id=" + id + ", code=" + code + ", name=" + name + ", parentCode=" + parentCode + "]";
}
}
3.添加数据库工具类
public class DBUtil{
private static DruidDataSource source;
static{
Properties properties = new Properties();
try {
properties.load(DBUtil.class.getClassLoader()
.getResourceAsStream("dbconfig.properties"));
} catch (IOException e) {
e.printStackTrace();
}
String username = properties.getProperty("username");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
source = new DruidDataSource();
source.setDriverClassName(driver);
source.setUrl(url);
source.setUsername(username);
source.setPassword(password);
}
public static Connection getConnection() {
try {
return source.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static void close(Connection conn,Statement statement,ResultSet resultSet){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
4.编写数据持久层
public class UserDao{
//获取所有省份
public List<Province> getProvinceList(){
List<Province> provinceList = new ArrayList<>();
Connection conn = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
conn = DBUtil.getConnection();
String sql = "select * from provinces where parent_code=?";
statement = conn.prepareStatement(sql);
statement.setString(1, "01");
resultSet = statement.executeQuery();
while (resultSet.next()) {
int id = resultSet.getInt("id");
String code = resultSet.getString("code");
String name = resultSet.getString("name");
Province province = new Province(id, code, name);
provinceList.add(province);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn, statement, resultSet);
}
return provinceList;
}
//获取省份对应城市
public List<City> getCityList(String parentCode){
List<City> cityList = new ArrayList<>();
Connection conn = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
conn = DBUtil.getConnection();
String sql = "select * from provinces where parent_code=?";
statement = conn.prepareStatement(sql);
statement.setString(1, parentCode);
resultSet = statement.executeQuery();
while (resultSet.next()) {
int id = resultSet.getInt("id");
String code = resultSet.getString("code");
String name = resultSet.getString("name");
City city = new City(id, code, name, parentCode);
cityList.add(city);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn, statement, resultSet);
}
return cityList;
}
}
5.编写Servlet
public class UserServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
private UserDao useDao = new UserDao();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String action = request.getParameter("action");
String parentCode = request.getParameter("parentCode");
if(action.equals("getProvinceList")){
List<Province> provinceList = useDao.getProvinceList();
String jsonStr = JSON.toJSONString(provinceList);
response.getWriter().write(jsonStr);
}else if(action.equals("getCityList")){
List<City> cityList = useDao.getCityList(parentCode);
String jsonStr = JSON.toJSONString(cityList);
response.getWriter().write(jsonStr);
}
}
}
6.编写前端页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>省市联动</h1>
<select id="province"></select>省
<select id="city"></select>市
<script type="text/javascript">
var province = document.getElementById("province");
var city = document.getElementById("city");
//获取省列表的函数
function getProvinceList() {
var xmlHttp = getXMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var text = xmlHttp.responseText;
//JSON解析
var provinceList = eval(text);
//控制是否添加城市
var bool = true;
//循环添加省份
for(var i = 0;i<provinceList.length;i++){
var option = document.createElement("option");
option.innerText = provinceList[i].name;
option.value = provinceList[i].code;
province.add(option);
if(bool){//第一个省就添加对应的市
getCityList(provinceList[i].code);
bool = false;
}
}
}
}
xmlHttp.open("GET","UserServlet?action=getProvinceList",true);
xmlHttp.send();
}
//获取市列表的函数
function getCityList(parentCode) {
var xmlHttp = getXMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var text = xmlHttp.responseText;
//JSON解析
var cityList = eval(text);
//先把城市列表置空
city.length = 0;
//循环添加城市
for(var i = 0;i<cityList.length;i++){
var option = document.createElement("option");
option.innerText = cityList[i].name;
option.value = cityList[i].code;
city.add(option);
}
}
}
xmlHttp.open("POST","UserServlet",true);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset-UTF-8");
xmlHttp.send("action=getCityList&parentCode=" + parentCode);
}
//一开始就调用获取省列表的函数
getProvinceList();
//给省绑定改变时间
province.onchange = function (){
getCityList(this.value);
}
function getXMLHttpRequest() {
var xmlHttp;
if (window.XMLHttpRequest) {// 新浏览器
xmlHttp = new XMLHttpRequest();
}else if (window. ActiveXObject) {// IE6及以下浏览器
xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP");
}
return xmlHttp;
}
</script>
</body>
</html>
6、总结
各位小可爱代码有点多呢,耐心看完,其实不难的,这是我自学的一些总结,希望能帮到大家,不喜勿喷哈哈,慢慢来嘛,相信以后会发布更高质量的博文