通俗易懂讲讲Ajax~



一、什么是Ajax

AJAX = Asynchronous JavaScript and XML:异步的 JavaScript 和 XML

传统来说,我们通过url请求一个链接,只有两种状态:转发重定向,但这两种方式都会将整个页面重构刷新

但是大部分时间,我们不需要刷新整个页面,我们只需要局部数据的更新,这就引入了ajax,我们可以将其看成异步无刷新请求

当我们在浏览器搜索框搜索一些内容时
image-20200911121649347
比如这里输入hexo,传统的方式,应该是页面刷新后才显示下面的数据

通过Ajax,我们输入搜索信息时,向服务器发起一个请求,从服务器请求回这些数据,通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新,不需要整个页面的刷新,就可以局部更新显示我们请求回的数据

我们可以检查验证一下,当我们在点击搜索框的一瞬间,就发起了一个请求
image-20200911123839289
当我们输入搜索内容时,发起了很多新的请求
image-20200911131048082

json是Ajax发送小部分数据的一种轻量级数据格式,可以简单易懂的给服务器或者浏览器交互数据,包括json对象,json数组对象。

我们可以点进去查看响应信息,就可以查看返回的json数据
image-20200911131132068

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"})

这些数据就是展示在前端的数据,就是我们搜索时,提示出来的数据

image-20200911131417107

总结:

  • AJAX不是一种新的编程语言,用于创建快速动态网页的技术
  • AJAX是在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。
  • AJAX不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
  • 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步局部更新
  • 传统的网页(即不用ajax技术的网页),想要更新内容或者提交一个表单,都需要重新加载整个网页。
  • 使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。



二、iframe标签简单伪造Ajax

我们编写一个html页面通过iframe标签来伪造Ajax的样子,在不刷新整个页面时局部更新部分数据

组成

  1. 输入文本框
  2. 提交按钮
  3. 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>

运行测试
image-20200908163829429
点击提交,就会在内嵌窗口内进行跳转,而不刷新整个页面
image-20200908163859728
以上实现了简单Ajax的样子,实现了发出请求,不刷新整个页面而是局部更新返回显示的效果




三、Ajax的实现

接下来我们讲讲真正Ajax的实现,但首先需要了解一些基本的概念

1. 基本概念的了解

对于Ajax的实现,我们首先需要了解一些基本的概念:

Ajax的核心是什么?

Ajax的核心是XMLHttpRequest对象(XHR),通过浏览器的XMLHttpRequest对象发出小部分数据,与服务端进行交互,服务端返回小部分数据,然后更新客户端的部分页面,浏览器端 异步 访问服务器

XMLHttpRequest是什么?

XMLHttpRequest简称XHR,用于在后台与服务器交换数据。

  • XHR为向服务器发送请求和解析服务器响应提供了接口,能够以异步方式从服务器获取新数据。
  • 所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。

Ajax数据传输的数据格式是什么?

Ajax常见的传输数据的格式有三种
image-20200911165506976
image-20200911165522593
image-20200911165606363
详细内容可以参考https://www.cnblogs.com/realshijing/p/8401294.html



2. 原生JS实现

这里参考了https://www.cnblogs.com/wxp5257/p/7929452.html

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:请求方式,GETPOST1.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项目

项目结构
image-20200907223516042

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项目搭建成功
image-20200908164822573


2. 下载jQuery

下载地址https://jquery.com/download/
image-20200908170440513

然后进入了https://code.jquery.com/jquery-3.5.1.js页面,里面就是Jquery的代码
image-20200908170653383
我们可以ctrl+s将js文件保存至本地


3. IDEA中引入jQeury文件

WEB-INF目录下新建statics包,用来放静态资源文件,然后再其下新建js包,用来放js文件
image-20200908170925351

然后将jQuery的js文件拷贝到js包

引入js静态资源后,就得在SpringMVC核心配置文件中加入静态资源过滤,过滤静态资源交给Web应用服务器默认的Servlet处理

<!--静态资源过滤-->
<mvc:default-servlet-handler/>

4. 在controller中编写一个请求方法

AjaxController中编写一个请求方法,请求路径位/ajax1

请求的参数为name,判断参数并打印truefalse

@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:服务器返回的数据类型,这里省略
    image-20200912131811144完整代码
<%@ 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
    image-20200911183718938

而当我们点击输入框,输入zsr,再点击外部任意处时,失去焦点发起请求,服务器响应后,再经回调函数处理,控制台打印了相关信息:

  • data:输入框的内容是zsr,后端返回true
  • status:成功执行请求响应,所以打印success
    image-20200911183915850

这就实现了前后端交互,并且实现了异步刷新(没有刷新页面后端就返回数据给前端)


7. 过程总结

总结:Ajax把主动权交给了前端

猜你喜欢

转载自blog.csdn.net/qq_45173404/article/details/108548626