一、什么是Ajax
AJAX
=Asynchronous JavaScript and XML
:异步的 JavaScript 和 XML
传统来说,我们通过url请求一个链接,只有两种状态:转发
、重定向
,但这两种方式都会将整个页面重构刷新
但是大部分时间,我们不需要刷新整个页面,我们只需要局部数据的更新,这就引入了ajax
,我们可以将其看成异步无刷新请求
当我们在浏览器搜索框搜索一些内容时
比如这里输入hexo
,传统的方式,应该是页面刷新后才显示下面的数据
通过Ajax
,我们输入搜索信息时,向服务器发起一个请求,从服务器请求回这些数据,通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新,不需要整个页面的刷新,就可以局部更新显示我们请求回的数据
我们可以检查验证一下,当我们在点击搜索框的一瞬间,就发起了一个请求
当我们输入搜索内容时,发起了很多新的请求
json
是Ajax发送小部分数据的一种轻量级数据格式,可以简单易懂的给服务器或者浏览器交互数据,包括json对象,json数组对象。
我们可以点进去查看响应信息,就可以查看返回的json
数据
jQuery110209003079113460963_1599801013609({
"q":"hexo","p":false,"g":[{
"type":"sug","sa":"s_1","q":"hexo搭建个人博客"},{
"type":"sug","sa":"s_2","q":"hexonia"},{
"type":"sug","sa":"s_3","q":"hexo是什么"},{
"type":"sug","sa":"s_4","q":"hexose"},{
"type":"sug","sa":"s_5","q":"hexokinase"},{
"type":"sug","sa":"s_6","q":"hexo主题推荐"},{
"type":"sug","sa":"s_7","q":"hexo可视化写博客"},{
"type":"sug","sa":"s_8","q":"hexo主题"},{
"type":"sug","sa":"s_9","q":"hexo博客"},{
"type":"sug","sa":"s_10","q":"hexonia攻略"}],"slid":"4771742357967452342","queryid":"0x1aea2648e55b8b6"})
这些数据就是展示在前端的数据,就是我们搜索时,提示出来的数据
总结:
AJAX
不是一种新的编程语言,用于创建快速动态网页的技术
AJAX
是在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。AJAX
不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
- 通过在后台与服务器进行少量数据交换,
AJAX
可以使网页实现异步局部更新
- 传统的网页(即不用ajax技术的网页),想要更新内容或者提交一个表单,都需要重新加载整个网页。
- 使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。
二、iframe标签简单伪造Ajax
我们编写一个html页面通过
iframe
标签来伪造Ajax的样子,在不刷新整个页面时局部更新部分数据
组成:
- 输入文本框
- 提交按钮
- iframe内嵌窗口
当点击提交按钮的时候,通过绑定jump
函数获取输入框内的url地址,并设置iframe窗口的src属性位该url,实现内嵌窗口跳转到指定网址
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>iframe体验页面无刷新</title>
<script>
function jump() {
var url = document.getElementById("url").value;
document.getElementById("window").src=url;
}
</script>
</head>
<body>
<div>
<p>请输入访问地址:</p>
<input type="text" id="url" value="https://blog.csdn.net/qq_45173404">
<input type="button" value="提交" onclick="jump()">
</div>
<div>
<iframe id="window" style="width: 100%;height:400px"></iframe>
</div>
</body>
</html>
运行测试:
点击提交,就会在内嵌窗口内进行跳转,而不刷新整个页面
以上实现了简单Ajax的样子,实现了发出请求,不刷新整个页面而是局部更新返回显示的效果
三、Ajax的实现
接下来我们讲讲真正Ajax的实现,但首先需要了解一些基本的概念
1. 基本概念的了解
对于Ajax的实现,我们首先需要了解一些基本的概念:
Ajax的核心是什么?
Ajax
的核心是XMLHttpRequest
对象(XHR
),通过浏览器的XMLHttpRequest
对象发出小部分数据,与服务端进行交互,服务端返回小部分数据,然后更新客户端的部分页面,浏览器端 异步 访问服务器
XMLHttpRequest是什么?
XMLHttpRequest
简称XHR
,用于在后台与服务器交换数据。
XHR
为向服务器发送请求和解析服务器响应提供了接口,能够以异步方式从服务器获取新数据。- 所有现代浏览器均支持
XMLHttpRequest
对象(IE5 和 IE6 使用 ActiveXObject)。
Ajax数据传输的数据格式是什么?
Ajax常见的传输数据的格式有三种
详细内容可以参考:https://www.cnblogs.com/realshijing/p/8401294.html
2. 原生JS实现
1. 创建XHR对象
各个浏览器对XHR
的支持也是不同的,给出下面方法来创建XHR
对象,以解决兼容问题
function createXMLHttpRequest() {
var xmlHttp;
// 适用于大多数浏览器,以及IE7和IE更高版本
try{
xmlHttp = new XMLHttpRequest();
} catch (e) {
// 适用于IE6
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
// 适用于IE5.5,以及IE更早版本
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
}
}
}
return xmlHttp;
}
2. 打开与服务器的连接
当得到XHR
对象后,就可以调用该对象的open()
方法打开与服务器的连接了。
open(method, url, async);
method
:请求方式,通常为GET或POST;url
:请求的服务器地址,若为GET请求,还可以在URL后追加参数;async
:这个参数可以不给,默认值为true,表示异步请求;
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("GET", "/ajax_get/?a=1", true);
3. 发送请求
当使用open打开连接后,就可以调用XHR
对象的send()
方法发送请求了。
send()
方法的参数为POST请求参数,即对应HTTP协议的请求体内容,若是GET请求,需要在URL后连接参数。
注意:若没有参数,需要给出null为参数!若不给出null为参数,可能会导致FireFox浏览器不能正常发送请求!
xmlHttp.send(null);
4. 接收服务器响应
当请求发送出去后,服务器端就开始执行了,但服务器端的响应还没有接收到。接下来我们来接收服务器的响应。
XHR
对象有一个onreadystatechange
事件,它会在XHR
对象的状态发生变化时被调用。
<%--XMLHttpRequest对象的5种状态--%>
0:初始化未完成状态,只是创建了XMLHttpRequest对象,还未调用open()方法;
1:请求已开始,open()方法已调用,但还没调用send()方法;
2:请求发送完成状态,send()方法已调用;
3:开始读取服务器响应;
4:读取服务器响应结束。
onreadystatechange
事件会在状态为1、2、3、4时引发。
但通常我们只关心最后一种状态4
,即读取服务器响应结束时,客户端才会做出改变。我们可以通过XHR
对象的readyState
属性来得到其状态
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4) {
alert('hello');
}
};
其实我们还要关心服务器响应的状态码
是否为200,其服务器响应为404,或500,那么就表示请求失败了。我们可以通过XHR
对象的status
属性得到服务器的状态码。
最后,我们还需要获取到服务器响应的内容,可以通过XHR
对象的responseText
得到服务器响应内容。
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
alert(xmlHttp.responseText);
}
};
3. jQuery实现
jQuery
是一个 JavaScript 库, 提供多个与AJAX
有关的方法。
- jQuery Ajax本质就是
XMLHttpRequest
,对其进行了封装,方便调用
1. 了解jQuery中Ajax的常用方法
$.ajax()
是jquery中通用的一个ajax封装
格式:
$.ajax({
type:'POST',
url:'发送请求的地址',
dataType:'服务器返回的数据类型',
data:{
key/value},
success:function(data){
//请求成功函数内容
},
error:function(jqXHR){
//请求失败函数内容
}
});
$.ajax({
type:'GET',
url:'发送请求的地址?数据名'+=数据内容[+"&数据名"+数据内容+...],
dataType:'服务器返回的数据类型',
success:function(data){
//请求成功函数内容
},
error:function(jqXHR){
//请求失败函数内容
}
});
部分参数:
url:请求地址
type:请求方式,GET、POST(1.9.0之后用method)
headers:请求头
data:要发送的数据
contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否异步
timeout:设置请求超时时间(毫秒)
beforeSend:发送请求前执行的函数(全局)
complete:完成之后执行的回调函数(全局)
success:成功之后执行的回调函数(全局)
error:失败之后执行的回调函数(全局)
accepts:通过请求头发送给服务器,告诉服务器当前客户端可接受的数据类型
dataType:将服务器端返回的数据转换成指定类型
"xml": 将服务器端返回的内容转换成xml格式
"text": 将服务器端返回的内容转换成普通文本格式
"html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
"script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
"json": 将服务器端返回的内容转换成相应的JavaScript对象
"jsonp": JSONP 格式使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
$.get()
使用GET方式来进行异步请求
语法结构:
$.get(url,[data],[callback])
url
:string类型,ajax请求的地址。
data
(可选参数):object类型,发送至服务器的key/value数据会附加到请求URL中
callback
(可选参数):function类型,当ajax返回成功时自动调用该函数
$.get({
url:'发送请求的地址'
data:{
key/value},
type:'服务器返回的数据类型',
success:function(data){
//请求成功函数内容
},
error:function(jqXHR){
//请求失败函数内容
}
});
$.post()
使用POST方式来进行异步请求
语法结构:
$.post(url,[data],[callback],[type])
同$.get()
类似,多了一个type
可选参数
type
:请求的数据类型,不设置就和$.get()
返回的数据格式一样,都是字符串的
$.post({
url:'发送请求的地址'
data:{
key/value},
type:'服务器返回的数据类型',
success:function(data){
//请求成功函数内容
},
error:function(jqXHR){
//请求失败函数内容
}
});
2. 模仿浏览器的失去焦点事件
1. 新建一个SpringMVC项目
项目结构:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.注册servlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--所有请求都会被springmvc拦截 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--SpringMVC内置过滤器,防止中文乱码-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
applicationContext.xml
:SpringMVC核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
<context:component-scan base-package="controller"/>
<!--注解驱动-->
<mvc:annotation-driven/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
AjaxController.java
package controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AjaxController {
@RequestMapping("/test")
public String test() {
return "test";
}
}
运行测试,访问http://localhost:8080/test
,正确显示结果则代表SpringMVC项目搭建成功
2. 下载jQuery
下载地址:https://jquery.com/download/
然后进入了https://code.jquery.com/jquery-3.5.1.js
页面,里面就是Jquery的代码
我们可以ctrl+s将js文件保存至本地
3. IDEA中引入jQeury文件
在WEB-INF
目录下新建statics
包,用来放静态资源文件,然后再其下新建js
包,用来放js文件
然后将jQuery
的js文件拷贝到js包
中
引入js静态资源后,就得在SpringMVC核心配置文件中加入静态资源过滤,过滤静态资源交给Web应用服务器默认的Servlet处理
<!--静态资源过滤-->
<mvc:default-servlet-handler/>
4. 在controller中编写一个请求方法
在
AjaxController
中编写一个请求方法,请求路径位/ajax1
请求的参数为name
,判断参数并打印true
或false
@RequestMapping("/ajax1")
public void ajax1(String name, HttpServletResponse response) throws IOException {
if ("zsr".equals(name))
response.getWriter().print("true");
else
response.getWriter().print("false");
}
5. 编写index.jsp测试页面
实现原理很简单,通过onblur
属性绑定当失去焦点事件,失去焦点时,调用onblurFunc()
函数,使用jquery的post()
方法发起一个post请求
我们查看post()
方法源码,发现实质上还是调用了jQuery.ajax()
函数 ,一共有四个参数
url
:请求的url地址data
:连同请求发送到服务器的数据,必须为key/value
的格式,key
的名字与controller中请求的参数名对应(这里发送的数据为name
)Callback
:回调函数,用来处理请求回来的数据(这里打印后端返回的数据data和执行状态)type
:服务器返回的数据类型,这里省略
完整代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<%--注意script标签一定要成对出现--%>
<script src="${pageContext.request.contextPath}/statics/js/jquery-3.5.1.js"></script>
<script>
function onblurFunc() {
$.post({
url: "${pageContext.request.contextPath}/ajax1",
data: {
"name": $("#username").val()},
success: function (data, status) {
console.log(data);//后端传来的数据
console.log(status);//执行状态
}
});
}
</script>
</head>
<body>
<%--onblur:失去焦点事件,失去焦点的时候,发起一个请求到后台--%>
用户名:<input type="text" id="username" onblur="onblurFunc()"/>
</body>
</html>
6. 启动Tomcat测试
当我们点击输入框,不输入内容,再点击外部任意处时,失去焦点发起请求,服务器响应后,再经回调函数处理,控制台打印了相关信息:
- data:输入框的内容不是
zsr
,后端返回false
- status:成功执行请求响应,所以打印
success
而当我们点击输入框,输入zsr
,再点击外部任意处时,失去焦点发起请求,服务器响应后,再经回调函数处理,控制台打印了相关信息:
- data:输入框的内容是
zsr
,后端返回true
- status:成功执行请求响应,所以打印
success
这就实现了前后端交互,并且实现了异步刷新(没有刷新页面后端就返回数据给前端)
7. 过程总结
总结:Ajax把主动权交给了前端
转载:https://blog.csdn.net/qq_45173404/article/details/108548626