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 ...
随机推荐
- ceph-csi源码分析(4)-rbd driver-controllerserver分析
更多ceph-csi其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 ceph-csi源码分析(4)-rbd driver-controllerserver分析 当 ...
- excel判断数据是否存在另一列中
1.if(EXACT(A2,B2)=TRUE,"相同","不同"),A2,B2相同(字母区分大小写)则函数值true正确,反馈相同,反之返回不同.注:单元格值受 ...
- 一文带你了解.Net信号量
本文主要讲解.Net基于Semaphore带大家了解信号量 信号量举例 大家去银行去银行取钱,互斥锁管理的时一个柜台是否正在处理业务,而信号量管理的是整个柜台是否正在处理业务,每当有一个柜台处理完成之 ...
- 9.10、mysql进程、状态在线修改参数重要知识
1.-e :改参数表示不用登陆mysql就可以使用mysql的命令,有利于于加管道符对数据进行处理: mysql -uroot -p123456 -e "show databases;&qu ...
- 13、mysql主从复制原理解析
13.1.mysql主从复制介绍: 1.普通文件,磁盘上的文件的同步方法: (1)nfs网络文件共享可以同步数据存储: (2)samba共享数据: (3)ftp数据同步: (4)定时任务:cronta ...
- Java数据库开发(二)之——DBCP连接数据库
1.载入jar包 DBCP需要以下几个jar包,可到apache及mysql的官网下载 2.程序编写 public static BasicDataSource ds = null; static f ...
- scRNAseq benchmark 学习笔记
背景 把早年没填完的坑(单细胞测序的细胞类型鉴别)给重新拾起来 其Github描述的基本情况: 作者并不对单个分类器进行说明,统一包装在benchmark工程里,还建立了docker容器 但说明了在s ...
- CTF反序列化逃逸
刷了一下CTF反序列化的题,去年没有好好了解.又补了一次PHP,害太菜了.每天看看别人的博客真的可以鼓舞人.简单记录一下两道字符串逃逸问题 推荐一个反序列化总结的很好的笔记https://www.cn ...
- ARTS第九周
1.Algorithm:每周至少做一个 leetcode 的算法题2.Review:阅读并点评至少一篇英文技术文章3.Tip:学习至少一个技术技巧4.Share:分享一篇有观点和思考的技术文章 以下是 ...
- FTP传输
FTP传输 一.FTP服务–用来传输文件的协议 二.设置匿名用户访问的FTP服务(最大权限) ...