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 ...
随机推荐
- 如何回答面试中问到的Hibernate和MyBatis的区别
这边主要是写给那些准备去面试的(没什么经验的)应聘者看的,为了在面试中更好的回答这个问题,我做一个简单的梳理和总结. 作为一名职场新人,经历过多次的面试,由于在简历中提及了Hibernate和MyBa ...
- etcd 添加用户,授权特定目录
适用场景 多组共用etcd集群,创建一个新用户.新目录,让这个新用户只有新目录的使用权限. 命令和顺序 创建目录,注意此处是v2 curl -u root:pwd http://host:2379/v ...
- 手摸手,带你用Beego撸商城系列一(基础篇)
完整项目地址: go-shop-b2c 系列文章: 手摸手,带你用 Beego撸商城 系列一(基础篇) 手摸手,带你用 Beego撸商城 系列二(登录篇) 手摸手,带你用 Beego撸商城 系列三(系 ...
- 循序渐进BootstrapVue,开发公司门户网站(5)--- 使用实际数据接口代替本地Mock数据
在我们开发一些门户网站功能的时候,有时候我们需要快速的创建数据模型来进行数据展示,因为数据结构可能处于不断的修正变化之中,因此服务端的接口我们可以暂时不开发,当我们基本完成数据结构和界面展示的时候,就 ...
- 全面解析Pytorch框架下模型存储,加载以及冻结
最近在做试验中遇到了一些深度网络模型加载以及存储的问题,因此整理了一份比较全面的在 PyTorch 框架下有关模型的问题.首先咱们先定义一个网络来进行后续的分析: 1.本文通用的网络模型 import ...
- Linux系统安装-C7
1.安装部署操作系统 (1)创建虚拟机,加载系统镜像 (2)进入系统引导界面进行配置 补充:centos7系统网卡名称 默认系统的网卡名称为 eth0 eth1 –centos6 默认系统的网卡名称为 ...
- 腾讯云TKE-基于 Cilium 统一混合云容器网络(下)
前言 在 腾讯云TKE - 基于 Cilium 统一混合云容器网络(上) 中,我们介绍 TKE 混合云的跨平面网络互通方案和 TKE 混合云 Overlay 网络方案.公有云 TKE 集群添加第三方 ...
- linux 查看目录大小
查看当前目录下各个目录大小容量 du -sh * du -sh /app/* du -h --max-depth=1 .
- 22、正则表达式(用于三剑客grep,awk,sed,内容中包含空行)
简单的说就是为处理大量的字符串而定义的一套规则和方法,通过定义特殊符号的辅助,系统管理员就可以快速过滤,替换城输出需要的字符串 : ^:^word 表示匹配以什么字符开头的内容: $:word$表示匹 ...
- UVA 10887 set或hash
题意: 给出n个A串和m个B串,将这A串与B串连接(B接在A后面)可以生成n*m个AB串,求不同的AB串的数量 分析: set直接水过 #include <bits/stdc++.h> u ...