AJAX的学习与使用>前端技术系列
AJAX的学习与使用
什么是AJAX
AJAX的全称为 Asynchronous JavaScript And XML 翻译为异步的javascript和xml,是一种可以实现发送异步请求的技术。
为什么要使用AJAX
传统的同步请求:页面需要不停的跳转、用户体验度差、无法实现局部刷新、速度慢(每次请求都需要返回一整个页面)
AJAX的异步请求:可以异步的向服务器发送请求,速度更快(只需要获取到数据,通过js动态加载)、可以实现局部刷新
其AJAX的最大特点就是:异步访问(快),局部刷新(用户体验度好)
AJAX接收服务器响应数据的3种格式
文本格式(重要)
javascript需要这样接收:xhr.responseText
,xhr 是XMLHttpRequest对象
所谓文本格式、就是服务器在接收请求时,返回一个字符串的文本数据。例如:
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.write("这是一段文本数据");
JSON格式(重要)
javascript需要这样接收:xhr.responseText
,xhr 是XMLHttpRequest对象,但是需要使用 eval()或者JSON.parse(这个要求key也必须是字符串,使用单引号或者双引号括起来的)转换
什么是JSON格式,就是一种规范的数据格式,格式如下
{"name":"zhangsan","age":"18"}
服务器端响应实体类JSON格式的3种方式
修改实体类的toString方法(不推荐)
修改前:
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
修改后(去掉了前面的Student,并将等于号替换成了英文的冒号):
@Override
public String toString() {
return "{" +
"name:'" + name + '\'' +
", age:" + age +
'}';
}
手动拼接一个JSON格式的数据(不推荐)
使用google的Gosn类库将实体类转换为JSON数据(推荐)
- 在WEB-INF/lib目录下放入Gosn的jar包
- 将jar包添加到类路径中
- 使用示例
resp.setContentType("text/html;charset=UTF-8");
// 封装Josn数据
Student student = new Student("张三",19);
String json = new Gson().toJson(student);
// 响应数据
PrintWriter out = resp.getWriter();
out.write(json);
XML格式(了解,得到的是一个DOM对象,可以使用getElementById等方法)
javascript需要这样接收:xhr.responseXML
,xhr 是XMLHttpRequest对象
// 注意,ContentType修改了
resp.setContentType("text/xml;charset=UTF-8");
// 封装XML数据
String xmlData = "<students>" +
"<student>" +
"<name>zhangsan</name>" +
"<age>18</age>" +
"</student>" +
"<student>" +
"<name>lisi</name>" +
"<age>29</age>" +
"</student>" +
"</students>";
// 响应数据
PrintWriter out = resp.getWriter();
out.write(xmlData);
使用原生javascipt进行发送get与post请求并接收数据
get请求
- 服务器端(这里博主自己封装了个BaseServlet,所以可以通过/ajax/方法名的方式访问到,我会将BaseServlet的代码放到最后)
@WebServlet(urlPatterns = "/ajax/*")
public class AjaxServlet extends BaseServlet {
public void dataType(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=UTF-8");
Student student = new Student("张三",18);
String json = new Gson().toJson(student);
resp.getWriter().write(json);
}
}
- 前端
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<base href="<%=request.getContextPath() + "/"%>">
<script type="text/javascript" charset="UTF-8">
var xhr;
function demo1() {
// 1、创建对象
xhr = new XMLHttpRequest();
// 2、建立连接
// method: string, url: string, async: boolean, username?: string | null, password?: string | null
// 请求方式、请求地址、是否异步(默认为true),用户名,密码(最后两个在tomcat有密码时才会用到)
xhr.open("get","ajax/dataType");
// 3、回调函数
xhr.onreadystatechange = process;
// 4、发送数据
xhr.send(null);
}
// 这个回调函数一般会被执行3次,待会通过讲解HTTP状态的问题来细说
function process() {
// xhr.readyState指的是当前的HTTP就绪状态,4代表服务器相应完成。
// xhr.status是服务器response响应的状态码,200代表成功
if(xhr.readyState == 4 && xhr.status == 200) {
// 这里由于接收的是一个JSON数据格式,但是拿到的是一个string,需要进行转换
var result = xhr.responseText;
eval("var newResult= " + result);
// 另一种转换方式
var newResult2 = JSON.parse(result);
console.log(newResult)
console.log(newResult2)
// 获取json中的数据
console.log(newResult.name + "---" + newResult.age);
console.log(newResult2.name + "---" + newResult2.age);
}
}
</script>
</head>
<body onload="demo1()">
</body>
</html>
- 访问页面后按F12的控制台查看结果
post请求
- 服务器端(不变,跟get请求保持一致,如果需要接收数据,使用request.getParameter即可)
- 前端
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<base href="<%=request.getContextPath() + "/"%>">
<script type="text/javascript" charset="UTF-8">
var xhr;
function demo1() {
// 1、创建对象
xhr = new XMLHttpRequest();
// 2、建立连接
xhr.open("post","ajax/dataType");
// 设置请求的ContentType,告诉服务器发送的是 文本格式,这句一定要放在建立连接之后
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
// 3、回调函数
xhr.onreadystatechange = process;
// 4、发送数据
xhr.send("name=liming&age=99");
}
function process() {
if(xhr.readyState == 4 && xhr.status == 200) {
var result = xhr.responseText;
var newResult = JSON.parse(result);
console.log(newResult)
}
}
</script>
</head>
<body onload="demo1()">
</body>
</html>
HTTP的就绪状态(5种)
通过XMLHttpRequest对象打点的方式可以获取到当前HTTP的就绪状态 xhr.readyState,就绪状态一共分为以下五种。
- 0:尚未建立连接时的状态,也就是在xhr.open()建立连接之前
- 1:连接已经建立,但是还没有发出请求,在 xhr.send()之前
- 2:请求已经发出且正在处理当中(此时一般可以获得到响应头信息)
- 3:请求已经处理,已经开始响应数据回客户端,但是还没有响应完成,只可以取得部分数据
- 4:请求处理完毕,数据已经响应完成
使用原生AJAX的注意事项
- 使用post请求时需要在建立连接后设置ContentType,内容为默认文本格式,如果需要传输二进制的数据:例如文件,则需要使用 multipart/form-data
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
- 发送数据时,如果是get请求,则直接把数据放在url中即可。
- 发送数据时,如果是post请求,需要在send()方法中使用键值对的方式传递参数,例如
xhr.send("name=liming&age=99");
使用jquery来进行ajax的异步请求
服务器端代码
public void jqueryAjax(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=UTF-8");
req.setCharacterEncoding("UTF-8");
System.out.println(req.getParameter("name"));
System.out.println(req.getParameter("age"));
Student student = new Student("张三",18);
String json = new Gson().toJson(student);
resp.getWriter().write(json);
}
经典版的异步请求
// 经典jquery的ajax请求方式
$.ajax({
type: "post", // 请求方式
url: "ajax/jqueryAjax", // 请求地址
async: true, // 是否异步请求,默认为true
data: {"name":"张三","age":"20"},
// data: "name=张三&age=20", 两种发送数据的方式都支持
contentType: "application/x-www-form-urlencoded", // 发送给服务器端的数据以何种方式编码,这是默认值
dataType: "json",// 以何种方式接收服务器响应的数据
success: function (result) { // 当服务器响应成功后,result为服务器响应的结果
console.log(result)
},
error: function (errorResult) { // 服务器响应错误时,跳转到该回调函数
console.log(errorResult)
}
});
精简版的get、post请求
//精简版的请求方式, post请求
$.post("ajax/jqueryAjax", {"name":"zhangsan","age":15}, function (result) {
console.log("这里是服务器响应的数据:" + result)
},"text");
// // 精简版的请求方式, get请求,会自动将数据拼接到URL中
$.get("ajax/jqueryAjax", {"name":"zhangsan","age":15}, function (result) {
console.log("这里是服务器响应的数据:" + result)
},"text");
小案例:三级联动列表的制作
环境搭建
- 准备数据库,数据库字段结构,其中pid自关联主键id
create table area(
id int primary key,
name varchar(32),
pid int
)
- 创建一个web项目并部署到tomcat中
- 在WEB-INF/lib中添加所需要的jar包(mybaits、mysql-connection、gson、lombok等)并添加到类路径中
- 引入mybatis.xml、log4j.properties、jdbc.properties等配置文件到src目录下
- 在src目录下创建好目录结构:mapper、service、entity、servlet、util等
服务端接口
@WebServlet("/three/*")
public class ThreeUniqueServlet extends BaseServlet{
public void threeUniqueData(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 设置响应编码
resp.setContentType("text/html;charset=UTF-8");
// 1、接收参数
int pid = Integer.parseInt(req.getParameter("pid"));
// 2、处理结果
AreaService areaService = new AreaServiceImpl();
List<Area> moreByPid = areaService.findMoreByPid(pid);
String json = new Gson().toJson(moreByPid);
// 3、返回结果
resp.getWriter().print(json);
}
}
前端代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<base href="<%=request.getContextPath() + "/"%>">
<script src="js/jquery-1.12.3.min.js" charset="UTF-8"></script>
<script type="text/javascript" charset="UTF-8">
$(function () {
// 在页面加载时初始化市
$.post("three/threeUniqueData",{pid: 0},function (result) {
for(var it of result) {
$('#shi').append('<option value = '+ it.id +'>'+ it.name +'</option>')
}
},'json');
// 为市设置变更事件
$("#shi").change(function () {
var id = $('#shi').val();
$.post('three/threeUniqueData',{pid:id},function (result) {
// 清空省和县的数据
$('#sheng').html('<option>-----请选择-----</option>');
$('#xian').html('<option>-----请选择-----</option>');
for(var it of result) {
$('#sheng').append('<option value = '+ it.id +'>'+ it.name +'</option>');
}
},'json');
});
// 为省设置变更事件
$("#sheng").change(function () {
var id = $('#sheng').val();
$.post('three/threeUniqueData',{pid:id},function (result) {
$('#xian').html('<option>-----请选择-----</option>');
for(var it of result) {
$('#xian').append('<option value = '+ it.id +'>'+ it.name +'</option>');
}
},'json');
});
});
</script>
</head>
<body>
市
<select id="shi">
<option>-----请选择-----</option>
</select>
省
<select id="sheng">
<option>-----请选择-----</option>
</select>
县
<select id="xian">
<option>-----请选择-----</option>
</select>
</body>
</html>
封装BaseServlet
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、获取servletPath
String servletPath = req.getRequestURI();
// 2、获取方法名
int start = servletPath.lastIndexOf("/") + 1;
int end = servletPath.lastIndexOf("?") != -1 ? servletPath.lastIndexOf("?") : servletPath.length();
String methodName = servletPath.substring(start, end);
try {
// 3、通过方法名获得方法,并执行
Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this, req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
``
AJAX的学习与使用>前端技术系列的更多相关文章
- 大前端技术系列:TWA技术+TensorFlow.js => 集成原生和AI功能的app
大前端技术系列:TWA技术+TensorFlow.js => 集成原生和AI功能的app ( 本文内容为melodyWxy原作,git地址:https://github.com/melodyWx ...
- 深度学习的异构加速技术(一):AI 需要一个多大的“心脏”?
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:kevinxiaoyu,高级研究员,隶属腾讯TEG-架构平台部,主要研究方向为深度学习异构计算与硬件加速.FPGA云.高速视觉感知等方向 ...
- 绝版珍珍藏:web前端技术学习指南
绝版珍珍藏:web前端技术学习指南 优秀的Web前端开发工程师要在知识体系上既要有广度和深度!应该具备快速学习能力. 前端开发工程师不仅要掌握基本的Web前端开发技术,网站性能优化.SEO和服务器端的 ...
- 前端技术Jquery与Ajax使用总结
前端技术Jquery与Ajax使用总结 虽然主要是做的后端,但是由于有些时候也要写写前台的界面,因此也就学习了下Jquery和Ajax的一些知识,虽说此次写的这些对于前端大神来说有些班门弄斧的感觉,但 ...
- 开始学习web前端技术
不能再蹉跎了,不能再徘徊了,不能再犹豫了,犹豫徘徊等于白来…… 感觉之前浪费了太多的岁月,必须得学习一门实用的技术来充实自己空虚的心情了. 想来想去网页应该是万金油的,大大小小多多少少都得用到.既然如 ...
- HTML5学堂 全新的HTML5/前端技术分享平台
HTML5学堂 全新的HTML5/前端技术分享平台 HTML5学堂是做什么的? HTML5学堂~http://www.h5course.com~由多名热爱H5的讲师们组成的一个组织.致力于构建一个前端 ...
- 前端安全系列(一):如何防止XSS攻击?
原文:https://my.oschina.net/meituantech/blog/2218539 前端安全 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全 ...
- ajax基础学习
AJAX即"Asynchronous JavaScript and XML",意思是异步JavaScript和XML,是指一种创建交互式网页的网页开发技术. 虽然现在很少有人去自己 ...
- 最受欢迎web前端技术总结
Web前端技术发展非常快,主流技术的进步.想想刚毕业那会用asp技术.目前,该网站已经非常少见主流应用. 后来的后来J2EE框架.然后SpringMVC声望,然而,最近的各种js框架广泛传播,Html ...
随机推荐
- 轻松吃透实时时钟芯片DS1302软硬件设计,看完秒懂
今天我们来讨论一款老掉牙的实时时钟芯片DS1302.什么是实时时钟(RealTime Clock, RTC)呢?为什么我们需要它呢?假设你使用单片机实现万年历应用,一般的做法是这样的:设置中断后判断1 ...
- VisualEffectGraph概述
Visual Effect Graph 由来: Visual Effect Graph 是2018.3 以后版本,出的新的粒子特效技术.它是用显卡渲染特效,区别于传统的Patical system 的 ...
- .Net EF Core千万级数据实践
.Net 开发中操作数据库EF一直是我的首选,工作和学习也一直在使用.EF一定程度的提高了开发速度,开发人员专注业务,不用编写sql.方便的同时也产生了一直被人诟病的一个问题性能低下. EF Core ...
- 携程二面:讲讲 MySQL 中的 WAL 策略和 CheckPoint 技术
前段时间我在准备暑期实习嘛,这是当时面携程的时候二面的一道问题,我一脸懵逼,赶紧道歉,不好意思不知道没了解过,面试官又解释说 redo log,我寻思着 redo log 我知道啊,WAL 是啥?给面 ...
- CS 面试题目总结(问题+答案)
开源了一个新的github仓库CS 面试题目总结(问题+答案),主要总结一些CS大厂常见的面试问题,所有的问题与答案参考了网络上的许多博客和github仓库,也希望各位读者能够对这个仓库进行补充,毕竟 ...
- 2、SpringBoot整合之SpringBoot整合servlet
SpringBoot整合servlet 一.创建SpringBoot项目,仅选择Web模块即可 二.在POM文件中添加依赖 <!-- 添加servlet依赖模块 --> <depen ...
- 9.4、安装zabbix(3)
(10)监控mysql: 1)安装mariadb-server: [root@slave-node1 ~]# yum install mariadb-server [root@slave-node1 ...
- js 获取系统当前时间,判断时间大小
1.获取系统当前时间 getNowTime(tempminit) { if (!tempminit) { tempminit = 0; } var date = new Date(); date.se ...
- redis集群搭建中遇到的一些问题
redis单机模式启动后,修改完配置文件,使用以下命令创建redis集群: sudo ./src/redis-trib.rb create --replicas 1 ip1:6379 ip2:6379 ...
- java_线程创建的三种方式及区别
java中关于线程的创建有三种: (1)通过继承Thread类创建线程. (2)通过实现Runnable接口创建线程. (3)通过Callable 和 Future 接口创建线程. * * * * * ...