Ajax (Asynchronous Javascript And XML)(异步 JavaScript 和 XML),无需重新加载整个网页的情况下,能够更新部分网页的技术。(异步刷新)
场景:看电影看了一半,点赞
- 全局刷新:访问后台,全局刷新,视频重新加载,崩溃
- 异步刷新:访问后台,只刷新点赞数,视频无需重新加载
一、基于XML的Ajax
JavaScript实现Ajax(基于XML),需要操作一个对象XMLHttpRequest对象
1.1 XMLHttpRequest对象的常用方法
-
open(method,url,true):与服务器建立连接
- method:请求方式
- url:服务器地址
- true:固定写法,是否为异步请求
-
send():发送参数
- get方式:send(null),直接在url发送参数(?xxx=xxx&yyy=yyy)
- post方式 :send(参数值)
- json数据需要 JSON.stringify() 封装
-
setRequestHeader(header,value):设置请求头
-
get方式:不需要此方法(get方式没有请求头)
-
post方式:需要设置
-
请求元素中包含文件上传:
setRequestHeader(“Content-Type”,“multipart/form-data”)
- 注意:如果使用FormData对象,不用设置,FormData默认使用multipart/form-data
-
不包含文件上传
setRequestHeader(“Content-Type”,“application/x-www-form-urlencoded”)
-
json数据
setRequestHeader(“Content_Type”,“application/json”)
-
-
-
onreadyStatechange:回调函数
-
readyState:请求状态 只有状态为4代表请求完毕
-
stauts:响应状态 只有200代表响应正常
-
responseText:响应格式String
-
responseXML:响应格式XML
1.2 POST请求
前台jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" >
//点击事件
function testClick(){
//获取name的值
var name =document.getElementById("n").value ;
//创建XMLHttpRequest对象连接后台
xr = new XMLHttpRequest();
//连接后台
xr.open("post","${pageContext.request.contextPath}/test/json",true);
//设置回调函数
xr.onreadystatechange=callback ;
//设置请求头
xr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//发送参数
xr.send("name="+name);
}
//回调函数
function callback(){
//请求正常和响应正常
if (xr.readyState==4&&xr.status==200){
var result = xr.responseText;
alert(result)
if (result=="success"){
alert("服务器接收到参数")
}else{
alert("服务器未接收到参数")
}
}
}
</script>
</head>
<body>
姓名<input id="n" name="name" >
<input type="button" value="提交" οnclick="testClick()">
</body>
</html>
服务器
方式一:原生servletAPI响应
@RequestMapping(value = "json" ,method = RequestMethod.POST)
public void json(String name, HttpServletResponse response) throws IOException {
if (name!=null&name.length()!=0){
System.out.println(name);
response.getWriter().write("success");
}else{
response.getWriter().write("error");
}
}
方式二:SprigMVC的ResponseBody响应
@ResponseBody
@RequestMapping(value = "json" ,method = RequestMethod.POST)
public String json(String name) {
if (name!=null&name.length()!=0){
System.out.println(name);
return "success" ;
}else{
return "error" ;
}
}
执行结果:
1.3 GET请求:(没有请求头,参数写在url上)
<script type="text/javascript" >
//点击事件
function testClick(){
//获取name的值
var name =document.getElementById("n").value ;
//创建XMLHttpRequest对象连接后台
xr = new XMLHttpRequest();
//连接后台
xr.open("get","${pageContext.request.contextPath}/test/json?name="+name,true);
//设置回调函数
xr.onreadystatechange=callback ;
//发送参数
xr.send(null);
}
//回调函数
function callback(){
//请求正常和响应正常
if (xr.readyState==4&&xr.status==200){
var result = xr.responseText;
alert(result)
if (result=="success"){
alert("服务器接收到参数")
}else{
alert("服务器未接收到参数")
}
}
}
</script>
1.4 Json格式数据传送
<script type="text/javascript" >
function testClick(){
var name =document.getElementById("n").value ;
xr = new XMLHttpRequest();
xr.open("post","${pageContext.request.contextPath}/test/json",true);
xr.onreadystatechange=callback ;
//设置请求头
xr.setRequestHeader("Content-Type","application/json");
//发送参数
xr.send(JSON.stringify({"accountName":name,"accountId":"001"}));
}
</script>
1.5 基于XML的Ajax文件上传
使用formData对象封装form表单中的文件与普通参数
- 使用append(”name“,value)方法添加参数,name为参数名,value为值
- 使用getElementById(“id”).files 获取文件数组
- 使用getElementById(“id”).value 获取参数值
注意:
- formData传递参数默认的enctype为multipart/form-data,所以不需要再设置请求头(会报错)
- 若使用SpringMVC中的multipartResolver解析参数,则request中已经没有文件,所以再使用ServletFileupload解析request为空
- SpringMVC解析与ServletFileupload解析不能混用
1.5.1 ServletFileupload方式上传文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" >
//点击事件
function testClick(){
//获取表单name的值
var name =document.getElementById("n").value ;
//获取表单file的值
var file =document.getElementById("file").files ;
var data = new FormData();
data.append("name",name);
data.append("file",file[0]);
//创建XMLHttpRequest对象连接后台
xr = new XMLHttpRequest();
//连接后台
xr.open("post","${pageContext.request.contextPath}/test/json",true);
//设置回调函数
xr.onreadystatechange=callback ;
//不能再设置请求头为multipart/form-data
// xr.setRequestHeader("Content-Type","multipart/form-data");
//发送参数
xr.send(data);
}
//回调函数
function callback(){
//请求正常和响应正常
if (xr.readyState==4&&xr.status==200){
var result = xr.responseText;
alert(result);
if (result=="success"){
alert("上传成功")
}else{
alert("上传失败")
}
}
}
</script>
</head>
<body>
姓名<input id="n" name="name" ><br>
文件<input id="file" name="file" type="file"><br>
<input type="button" value="提交" οnclick="testClick()">
</body>
</html>
@ResponseBody
@RequestMapping(value = "/json" ,method = RequestMethod.POST)
public String json(HttpServletRequest request) throws Exception {
//获取项目的绝对路径+/upLoad/
String path = request.getSession().getServletContext().getRealPath("/upLoad/");
//控制打印项目真实地址
System.out.println(path);
File file = new File(path);
//判断文件夹是否存在
if (!file.exists()) {
//创建文件夹
file.mkdirs();
}
//判断前台数据是否有multipart/form-data
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
//不存在Multipart
if (!isMultipart){
return "error" ;
}
//创建FileItem工厂
FileItemFactory fileItemFactory = new DiskFileItemFactory() ;
//创建文件上传Servlet(需要一个FileItem工厂)
ServletFileUpload fileUpload = new ServletFileUpload(fileItemFactory);
//解析request
List<FileItem> fileItems = fileUpload.parseRequest(request);
//生成迭代器
Iterator<FileItem> iterator = fileItems.iterator();
//遍历迭代器
while(iterator.hasNext()){
FileItem fileItem = iterator.next();
//判断是否为文件类型
if (fileItem.isFormField()){
//普通类型
//获取参数名称
String name = fileItem.getFieldName();
//获取参数值(指定字符集)
String value = fileItem.getString("UTF-8");
//控制台打印参数
System.out.println(name+"="+value);
}else{
//文件类型
String fileName = fileItem.getName();
//使用UUID定义唯一文件名
String uuid = UUID.randomUUID().toString().replace("-", "");
//上传文件
fileItem.write(new File(file,uuid+"_"+fileName));
//删除内存中的临时文件
fileItem.delete();
//控制台打印测试
System.out.println(fileItem.getFieldName()+"上传成功");
return "success" ;
}
}
return "error" ;
}
1.5.2 SpringMVC方式上传文件
注意:MultipartFile与前台的文件名要一致
配置CommonsMultipartResolver的bean
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="102400">
</property>
</bean>
测试
//注意MultipartFile与前台的文件名要一致
@ResponseBody
@RequestMapping(value = "/json" ,method = RequestMethod.POST)
public String json(@RequestParam("name")String name , MultipartFile multipartFile ,HttpServletRequest request) throws Exception {
//获取项目的绝对路径+/upLoad/
String path = request.getSession().getServletContext().getRealPath("/upLoad/");
//控制打印项目真实地址
System.out.println(path);
File file = new File(path);
//判断文件夹是否存在
if (!file.exists()) {
//创建文件夹
file.mkdirs();
}
//控制台打印测试name参数
if (name!=null)
System.out.println(name);
if (multipartFile!=null){
//获取文件名
String fileName = multipartFile.getOriginalFilename();
//使用UUID定义唯一文件名
String uuid = UUID.randomUUID().toString().replace("-", "");
//上传文件
multipartFile.transferTo(new File(file,uuid+"_"+fileName));
//控制台打印测试
System.out.println("上传成功");
return "success" ;
}
return "error" ;
}
二、基于JQuery的Ajax
参考网站:常用方法参数
方法常用参数:
-
url: 发送请求的地址
-
type: 请求方式(post或get)默认为get
-
data :String或Object类型(post请求),get请求在url中指定
-
String类型:key1=value1&key2=value2…
-
Object类型:json数据{key1 : value , key2 : value2 , … }为单个对象,集合
形式为:[ {key1 : value , key2 : value2 , … } , {key1 : value , key2 : value2 , … } … ]
-
dataType : 服务器返回的数据类型
-
json:json数据
-
text:纯文本格式
-
……
-
success: 请求成功时回调函数,有两个参数 ( function(data , status ){} )
- data:服务返回数据
- status:状态码
-
error : 请求失败时调用的函数
-
contentType:内容(参数)类型,默认为“application/x-www-form-urlencoded”
2.1 POST请求
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="static/jquery-3.4.1.js"></script>
<script type="text/javascript" >
$(function(){
//点击事件
$("#mybutton").click(function(){
//获取name参数的值
var $name = $("#n").val();
//ajax异步请求
$.ajax({
//请求方式
type: "post",
//请求路径
url: "test/json" ,
//请求参数
data: "name="+$name+"&age=12" ,
//成功回调函数
success:function(result){
if (result =="success"){
alert("成功");
}else if (result=="error"){
alert("失败");
}else{
alert("错误");
}
}
});
});
});
</script>
</head>
<body>
姓名<input id="n" name="name" ><br>
<input id="mybutton" type="button" value="提交" >
</body>
</html>
@RequestMapping("/json")
@ResponseBody
public String json(String name,Integer age){
System.out.println(name);
System.out.println(age);
return name==null||age==0 ? "error" : "success" ;
}
2.2 GET方式请求
请求参数写在url上
<script type="text/javascript" src="static/jquery-3.4.1.js"></script>
<script type="text/javascript" >
$(function(){
$("#mybutton").click(function(){
var $name = $("#n").val();
$.ajax({
type: "get",
//请求参数写在url上
url: "test/json?name="+$name+"&age=23" ,
success:function(result){
if (result =="success"){
alert("成功");
}else if (result=="error"){
alert("失败");
}else{
alert("错误");
}
}
});
});
});
</script>
2.3 Json数据请求
Json格式:
- 键名称:用双引号 括起
- 字符串:用使用双引号 括起
- 数字,布尔类型不需要 使用双引号括起
<script type="text/javascript" src="static/jquery-3.4.1.js"></script>
<script type="text/javascript" >
$(function(){
$("#mybutton").click(function(){
var $name = $("#n").val();
$.post({
url:"test/json",
data:JSON.stringify({"accountId":23, "accountName":$name}),
contentType:"application/json;charset=utf-8",
success:function(result) {
if (result == "success") {
alert("成功");
} else if (result == "error") {
alert("失败");
} else {
alert("错误");
}
}
});
});
});
</script>
@RequestMapping("/json")
@ResponseBody
public String json(@RequestBody Account account){
System.out.println(account);
return account.getAccountName()==null||account.getAccountId()==0 ? "error" : "success" ;
}
2.4 Json数据响应
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="static/jquery-3.4.1.js"></script>
</head>
<body>
<input type="button" value="获取" id="getContent" ><br>
<table width="80%" align="center">
<tr>
<td>id</td>
<td>姓名</td>
</tr>
<tbody id="body"></tbody>
</table>
<script type="text/javascript" >
$(function(){
$("#getContent").click(function(){
alert("test");
var html = "" ;
//ajax请求数据
$.post("${pageContext.request.contextPath}/test/json",function(result){
//取出数据,拼接
for (var i = 0; i < result.length; i++) {
html+="<tr>"+
"<td>"+result[i].accountId+"</td>"+
"<td>"+result[i].accountName+"</td>"+
"</tr>";
}
//给表赋值
$("#body").html(html);
});
});
});
</script>
</body>
</html>
@RequestMapping("/json")
@ResponseBody
public List json(){
List<Account> list = new ArrayList<>();
Account account1 = new Account() ;
Account account2 = new Account() ;
account1.setAccountId(1);
account1.setAccountName("张三");
account2.setAccountId(2);
account2.setAccountName("李四");
list.add(account1);
list.add(account2);
return list ;
}
执行结果:
2.5 JQuery方式上传文件
Ajax方式中,需要设置:
- processData : false 使数据不做处理
- contentType : false 不要设置Content-Type请求头
2.5.1 ServletFileupload方式上传
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="static/jquery-3.4.1.js"></script>
</head>
<body>
<input type="text" name="name" id="n">
<input type="file" id="file">
<input type="button" value="获取" id="mybutton" >
<script type="text/javascript" >
$(function(){
//点击事件
$("#mybutton").click(function(){
//获取name参数的值
var $name = $("#n").val();
//获取文件数组
var file = document.getElementById("file").files ;
var formData = new FormData();
//name参数添加到formData中
formData.append("name",$name) ;
//获取文件数组中的一个元素,并添加到formData中
formData.append("multipartFile",file[0]) ;
//Ajax异步访问服务器
$.post({
url:"test/json" ,
data: formData ,
contentType:false , //contentType不做处理,使用formData默认的multipart/form-data
processData: false , //使数据不做处理
//回调函数
success: function(result){
if (result=="success") {
alert("上传成功");
}else {
alert("上传失败");
}
}
});
});
});
</script>
</body>
</html>
@ResponseBody
@RequestMapping(value = "/json" ,method = RequestMethod.POST)
public String json(HttpServletRequest request) throws Exception {
//获取项目的绝对路径+/upLoad/
String path = request.getSession().getServletContext().getRealPath("/upLoad/");
//控制打印项目真实地址
System.out.println(path);
File file = new File(path);
//判断文件夹是否存在
if (!file.exists()) {
//创建文件夹
file.mkdirs();
}
//判断内容是否Multipart
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart)
return "error" ;
//创建FileItem工厂
FileItemFactory fileItemFactory = new DiskFileItemFactory();
//创建文件上传servlet
ServletFileUpload fileUpload = new ServletFileUpload(fileItemFactory);
//解析request
List<FileItem> fileItems = fileUpload.parseRequest(request);
//判断fileItems是否为空
if (fileItems==null)
return "error" ;
//生成迭代器
Iterator<FileItem> iterator = fileItems.iterator();
//取出每一个表单项
while (iterator.hasNext()){
FileItem item = iterator.next();
//判断是普通参数还是文件
if (item.isFormField()){//普通参数
//获取参数名
String fieldName = item.getFieldName();
//获取参数值,指定字符集
String value = item.getString("utf-8");
//打印结果
System.out.println(fieldName+"="+value);
}else {//文件
//获取文件名
String name = item.getName();
//使用uuid生成唯一字符串
String uuid = UUID.randomUUID().toString().replace("-", "");
//写出磁盘
item.write(new File(file,uuid+name));
//删除临时文件
item.delete();
//打印测试
System.out.println("上传文件成功");
return "success" ;
}
}
return "error" ;
}
执行结果:
2.5.2 SpringMVC方式上传
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="static/jquery-3.4.1.js"></script>
</head>
<body>
<input type="text" name="name" id="n">
<input type="file" id="file">
<input type="button" value="获取" id="mybutton" >
<script type="text/javascript" >
$(function(){
//点击事件
$("#mybutton").click(function(){
//获取name参数的值
var $name = $("#n").val();
//获取文件数组
var file = document.getElementById("file").files ;
var formData = new FormData();
//name参数添加到formData中
formData.append("name",$name) ;
//获取文件数组中的一个元素,并添加到formData中
formData.append("multipartFile",file[0]) ;
//Ajax异步访问服务器
$.post({
url:"test/json" ,
data: formData ,
contentType:false , //contentType不做处理,使用formData默认的multipart/form-data
processData: false , //使数据不做处理
//回调函数
success: function(result){
if (result=="success") {
alert("上传成功");
}else {
alert("上传失败");
}
}
});
});
});
</script>
</body>
</html>
@ResponseBody
@RequestMapping(value = "/json" ,method = RequestMethod.POST)
public String json(@RequestParam("name")String name ,
MultipartFile multipartFile ,
HttpServletRequest request) throws Exception {
//获取项目的绝对路径+/upLoad/
String path = request.getSession().getServletContext().getRealPath("/upLoad/");
//控制打印项目真实地址
System.out.println(path);
File file = new File(path);
//判断文件夹是否存在
if (!file.exists()) {
//创建文件夹
file.mkdirs();
}
//控制台打印测试name参数
if (name!=null)
System.out.println(name);
if (multipartFile!=null){
//获取文件名
String fileName = multipartFile.getOriginalFilename();
//使用UUID定义唯一文件名
String uuid = UUID.randomUUID().toString().replace("-", "");
//上传文件
multipartFile.transferTo(new File(file,uuid+"_"+fileName));
//控制台打印测试
System.out.println("上传成功");
return "success" ;
}
return "error" ;
}
执行结果: