AJAX技术简单介绍及使用

本文深入探讨了AJAX技术的工作原理及其在动态网页创建中的应用,包括异步JavaScript和XML的交互过程,以及如何使用JSON格式进行数据传输,对比XML,展示了JSON的优越性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AJAX

Asynchronous JavaScript And Xml :异步JavaScript和XML;
用于快速创建动态网页的技术;
对页面进行局部更新;

异步同步

同步方式:正常情况下,浏览器与服务器之间是串行操作,类似于一个Java线程的操作。
异步方式:浏览器与服务器是并行操作,类似于Java中多个线路同时工作。

AJAX使用的技术

JavaScript:用于后台发送数据给服务器,并且对服务器返回的结果进行处理。
XML:用于接收服务器返回的数据,但是已经被JSON格式代替。

原生AJAX

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Crhw5Im6-1593939140557)(C:\Users\computer\AppData\Local\Temp\1593172499571.png)]

流程说明:
1、用户在浏览器端由JS创建一个对象XMLHttpRequest对象
2、这个对象是ajax的核心对象,由它发送请求给服务器
3、将请求的数据发送到服务器
4、在服务器处理数据,从数据库中查询用户是否存在,通过XML(JSON)把数据返回
5、在回调函数中得到服务器返回的数据,使用HTML和CSS更新页面的信息

编写

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>原始AJAX</title>
    <script src="js/jquery-3.3.1.js"></script>
</head>
<body>
用户名:<input type="text" id="name"><span id="spa"></span>
<script type="text/javascript">
    document.getElementById("name").onchange = function () {
		//获取XMLHttpRequest对象
        let xhr = new XMLHttpRequest();
		//打开服务器连接;发送方式、地址、是否异步
        xhr.open("GET","Json/User.json",true);
		//发送请求
        xhr.send();
        let user = document.getElementById("name").value;
        let flag = false;
		//回调函数,状态改变时接收数据
        xhr.onreadystatechange = function () {
            //准备状态等于4,服务器状态码等于200;这样等于服务器成功响应
            if(xhr.status == 200 && xhr.readyState == 4){
                //接收响应数据
                let datas = xhr.responseText;//相应返回为字符串
          		//处理数据
                let das = JSON.parse(datas);
                for (let da of das) {
                    if(da == user){
                        flag = true;
                        break;
                    }
                }
                if(flag){
                    $("#spa").text("用户名重复!");
                    // document.getElementById("spa").innerText = "用户名重复!";
                }
                else {
                    $("#spa").text("恭喜,可以注册!");
                    // document.getElementById("spa").innerText = "恭喜,可以注册!";
                }
            }
        }
    }
</script>
</body>
</html>

使用方式

. g e t ( ) 和 .get()和 .get().post()方式

二者除提交方式和名称不一样外,其余参数完全一样;(3.0版本以前的使用方式)
使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.0以前get等方式的使用</title>
    <script src="js/jquery-3.3.1.js"></script>
</head>
<body>
用户名:<input type="text" id="name"><span id="spa"></span>
<script type="text/javascript">
    $("#name").change(function () {
        $.get("Json/User.json",//地址值;post方式为$.post();其余一样
              function (users) {//回调函数,接收响应数据
        	    let name = $("#name").val();
        	    let flag = false;
        	    for (let user of users) {
        	        if(user == name){
        	            flag = true;
        	            break;
        	        }
        	    }
        	    if(flag){
        	        $("#spa").text("用户名重复!");
        	    }else {
        	        $("#spa").text("恭喜,可以注册!");
        	    }
        	},
              "json"//响应数据格式
             );
    });
</script>
</body>
</html>

$.AJAX()方式

参数说明

$.ajax({键:值,键:值}) 属性名称解释
url服务器访问地址
async默认是异步,取值是true,设置为false表示同步
methodGET或POST方法,默认GET
data发送给服务器的数据,2种格式:
1. 键=值&键=值
2. {键:值, 键:值}
dataType服务器返回的数据类型
取值:xml, html, script, json, text
success服务器正常响应的回调函数,参数就是服务器返回的数据
error服务器出现异常的回调函数,参数是XMLHttpRequest对象
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>$.ajax实现用户登录</title>
    <script src="js/jquery-3.3.1.js"></script>
</head>
<body>
<form id="loginForm">
    <table>
        <tr>
            <td>用户名</td>
            <td><input type="text" name="username" id="username"/></td>
        </tr>
        <tr>
            <td>密码</td>
            <td><input type="password" name="password" id="password"/></td>
        </tr>
        <tr>
            <!--登录按钮是一个普通按钮-->
            <td colspan="2" align="center"><input type="button" value="登录" id="btnLogin"/></td>
        </tr>
    </table>
</form>
<script type="text/javascript">
    $("#btnLogin").click(function () {
        let name = $("#username").val();
        let password = $("#password").val();
        $.ajax({		//此处方法名称可以改为$.post()和$.get();3.0版本以后可以使用
            url:"Json/login.json",
            // async:true,//默认异步
            // method:"POST",//不写默认是get提交方式
            success:function (users) {//回调函数接收响应数据
                let flag = false;
                for (let user of users) {
                    if(user.name == name && user.password == password){
                        flag = true;
                        break;
                    }
                }
                if(flag){
                    alert("登录成功!" + name);
                }else{
                    alert("用户名或密码错误!");
                }
            },
            dataType:"json"//数据类型
        });
    });
</script>
</body>
</html>

JSON

概念: JavaScript Object Notation

作用

​ json现在多用于存储和交换文本信息的语法;
进行数据的传输;
JSON 比 XML 更小、更快,更易解析。

格式

 {
	"name":"张三",
	"age":23,
	"gender":"男"
}

前段json格式转换

方法说明
stringify对象转字符串
parse字符串转对象

后端json格式转换

ObjecrtMapper

  • writeValueAsString:字符串转json
  • readValue:json转字符串

案例

案例1、搜索联想词

需求

当在搜索框中输入关键字,搜索框下方显示相关联想词

步骤

1、前端页面获取输入关键字名称
2、前段根据关键字发送异步请求到后端请求数据
3、前段根据后端响应数据在页面上回写内容

模拟后端数据

json文件

[
  "张三",
  "李四",
  "王五",
  "赵六",
  "田七",
  "孙八",
  "张三丰",
  "张无忌",
  "李寻欢",
  "王维",
  "李白",
  "杜甫",
  "李贺",
  "李逵",
  "宋江",
  "王英",
  "鲁智深",
  "武松",
  "张薇",
  "刘小轩",
  "刘浩宇",
  "刘六"
]

前段页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自动补全</title>
    <style type="text/css">
        .content {
            width: 400px;
            margin: 30px auto;
            text-align: center;
        }

        input[type='text'] {
            box-sizing: border-box;
            width: 280px;
            height: 30px;
            font-size: 14px;
            border: 1px solid #38f;
        }

        input[type='button'] {
            width: 100px;
            height: 30px;
            background: #38f;
            border: 0;
            color: #fff;
            font-size: 15px;
        }

        #show {
            box-sizing: border-box;
            position: relative;
            left: 7px;
            font-size: 14px;
            width: 280px;
            border: 1px solid dodgerblue;
            text-align: left;
            border-top: 0;
            /*一开始是隐藏不可见*/
            display: none;
        }

        #show div {
            padding: 4px;
            background-color: white;
        }

        #show div:hover {
            /*鼠标移上去背景变色*/
            background-color: #3388ff;
            color: white;
        }
    </style>
    <script src="js/jquery-3.3.1.js"></script>
</head>
<body>
<div class="content">
    <img alt="传智播客" src="img/logo.png"><br/><br/>
    <input type="text" name="word" id="word">
    <input type="button" value="搜索一下">
    <div id="show"></div>
</div>
</body>
<script type="text/javascript">
    //当键盘松开事件,触发请求
    $("#word").keyup(function () {
		//获取输入数据
        let value = $("#word").val().trim();
		//防止null
        if(value == ""){
            $("#show").hide();
            return;
        }
		//发送异步请求
        $.post({
            url:"Json/search.json",
            success:function (datas) {
                let reg = new RegExp("^" + value);
                let arr = new Array();
                let html = "";
				//处理响应数据
                for (let data of datas) {
                    if(reg.test(data)){
                        arr.push(data);
                    }
                }
                if(arr.length == 0){
                    $("#show").hide();
                    return;
                }
				//回显数据
                for (let a of arr) {
                    html += "<div>" + a + "</div>";
                }
                $("#show").html(html);
                $("#show").fadeIn(500);
                $("#show div").click(function () {
                    let text = $(this).text();
                    $("#word").val(text);
                    $("#show").slideUp("normal");
                });
            },
            dataType:"json"
        });
    });
</script>
</html>

案例2分页

插件介绍

前端插件

css文件:simplePagination.css
js文件:jquery.simplePagination.js

使用
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
	//导入分页插件样式
    <link rel="stylesheet" href="css/simplePagination.css">
</head>
<body>
    //其固定样式div,必须这样写
    <div class="content">
        <div class="pagination-holder clearfix">
            <div id="light-pagination" class="pagination"></div>
        </div>
    </div>
</body>
//导入js文件,必须同时导入两个该文件
<script src="js/jquery-3.3.1.min.js"></script>
<script src="js/jquery.simplePagination.js"></script>
<script>
    //设置页数和当前页;必须是这样的格式
    $("#light-pagination").pagination({
        pages:10,
        currentPage:5
    });
</script>
</html>
效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yM7TifFu-1593939140568)(C:\Users\computer\AppData\Local\Temp\1593312393921.png)]

后端插件

导包:pageHelper-5.1.10.jar
方法:PageHelper.startPage(start,pageSize);
经过插件处理后,如果后续有查询数据,会自动封装到该对象中
使用

//封装Page对象   start:当前页码   pageSize:每页显示的条数;
 page = PageHelper.startPage(start,pageSize);

分页1:瀑布式

需要用到后端分页插件

需求

当滚动条向下滑动触底时显示更多数据;

使用技术

mybatis、jquery、ajax、mysql

步骤

1、页面加载显示一定数据;
2、当滚动条向下滑动触底请求服务器数据
3、处理服务器响应数据并回显到页面上

配置mybatis核心配置文件;log4j.properties文件,导包等等;

前端
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>网站首页</title>
    <link rel="stylesheet" href="css/tt.css">
</head>
<body>
<div class="top">
    <span class="top-left">下载APP</span>
    <span class="top-left"> 北京         晴天</span>
    <span class="top-right">更多产品</span>
</div>
<div class="container">
    <div class="left">
        <a>
            <img src="img/logo.png"><br/>
        </a>
        <ul>
            <li>
                <a class="channel-item active" href="#">
                    <span>
                        推荐
                    </span>
                </a>
            </li>
            <li><a class="channel-item" href="#">
                <span>
                    视频
                </span>
            </a></li>
			···
        </ul>
    </div>
    <div class="center">
		//页面加载时显示数据
        <ul class="news_list">
            <li>
                <div class="title-box">
                    <a href="#" class="link">
                        奥巴马罕见介入美国2020大选,警告民主党参选人须“基于现实11”
                        <hr>
                    </a>
                </div>
            </li>
			····
        </ul>
        <div class="loading" style="text-align: center; height: 80px">
            <img src="img/loading2.gif" height="100%">
        </div>
		<div class="content">
            <div class="pagination-holder clearfix">
                <div id="light-pagination" class="pagination"></div>
            </div>
        </div>	
        <div id="no" style="text-align: center;color: red;font-size: 20px"></div>
    </div>
</div>
</body>
<script src="js/jquery-3.3.1.js"></script>
<script>
    //1.定义发送请求标记
    let send = true;
    //2.定义当前页码和每页显示的条数
    let start=1;
    let size=10;
    //3.定义滚动条距底部的距离
    let bottom = 5;

    //4.设置页面加载事件
    $(function () {
        //5.为当前窗口绑定滚动条滚动事件;
	   //注意:初始加载页面数据问题(最开始加载数据的文档高度小于当前窗口高度,那么便不会触发滚动条滚动事件)
        $(window).scroll(function () {
            //6.获取必要信息,用于计算当前展示数据是否浏览完毕
            //当前窗口的高度
            let windowHeight = $(window).height();
            //当前滚动条从上往下滚动的距离
            let scrollTop = $(window).scrollTop();
            //当前文档的高度
            let docHeight = $(document).height();
            //7.计算当前展示数据什么时候浏览完毕
            //当 滚动条距底部的距离 + 当前滚动条滚动的距离 + 当前窗口的高度 >= 当前文档的高度
            if((bottom + scrollTop + windowHeight) >= docHeight){
                //8.判断请求标记是否为true
                if(send==true){
                    //9.将请求标记置为false,当前异步操作完成前,不能重新发起请求
                    send = false;
                    //10.根据当前页和每页显示的条数来 请求查询分页数据
                    queryInfo(start,size);
                    //11.当前页码+1
                    start++;
                }
            }
        });
    });

    //请求查询分页数据的函数
    function queryInfo(start, pageSize) {
        //将加载动图显示
        $(".loading").show();
        //发起AJAX异步请求
        $.ajax({
            url:"newsServlet",
            data:{"start":start,"pageSize":pageSize},
            success:function (datas) {
                if (datas.length == 0) {
                    $(".loading").hide();
                    $("#no").html("没了。。。");
                    return;
                }
                $(".loading").hide();
                let html = ``;
                for (let i = 0; i < datas.length; i++) {
                    html+=`<li>
                                <div class="title-box">
                                    <a href="#" class="link">
                                        ${datas[i].title}
                                        <hr>
                                    </a>
                                </div>
                            </li>`;
                }
                //追加到页面
                $(".news_list").append(html);
                //将请求标记置为true
                send=true;
            }
        })
    };
</script>
</html>

servlet

package com.itheima.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.itheima.service.NewsService;
import com.itheima.service.impl.NewsServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/newsServlet")
public class NewsServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置请求和响应的编码
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("applicaion/json;charset=UTF-8");

        //1.获取请求参数
        String start = req.getParameter("start");
        String pageSize = req.getParameter("pageSize");

        //2.根据当前页码和每页显示的条数,调用业务层的方法,得到分页Page对象
        NewsServiceImpl newsService = new NewsServiceImpl();
        Page page = newsService.pageQuery(Integer.parseInt(start), Integer.parseInt(pageSize));

        //3.将得到的数据转为json
        String s = new ObjectMapper().writeValueAsString(page);

        //模拟服务器加载数据需要1秒钟
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //4.将数据响应给客户端
        resp.getWriter().write(s);
        
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
}

service

package com.itheima.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.mapper.NewsMapper;
import com.itheima.service.NewsService;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class NewsServiceImpl implements NewsService {
    @Override
    public Page pageQuery(Integer start, Integer pageSize) {
        InputStream is = null;
        SqlSession sqlSession = null;
        Page page = null;
        try{
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过SqlSession工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);

            //4.获取NewsMapper接口的实现类对象
            NewsMapper mapper = sqlSession.getMapper(NewsMapper.class);

            //5.封装Page对象   start:当前页码   pageSize:每页显示的条数
            page = PageHelper.startPage(start,pageSize);

            //6.调用实现类对象的查询全部方法,此时底层执行的就是MySQL的limit分页查询语句
            mapper.selectAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //7.释放资源
            if(sqlSession != null) {
                sqlSession.close();
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //8.返回page对象
        return page;
    }
}

dao

public interface NewsMapper {
    /*
        查询全部
     */
    @Select("SELECT * FROM news")
    public abstract List<News> selectAll();
}

分页2:正常分页

需要使用上述前后端分页插件
操作基本类似瀑布式;
前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="css/simplePagination.css">
    <link rel="stylesheet" href="css/tt.css">
</head>
<body>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>网站首页</title>
    <link rel="stylesheet" href="css/tt.css">
</head>
<body>
<div class="top">
    <span class="top-left">下载APP</span>
    <span class="top-left"> 北京         晴天</span>
    <span class="top-right">更多产品</span>
</div>

<div class="container">

    <div class="left">
        <a>
            <img src="img/logo.png"><br/>
        </a>

        <ul>
            <li>
                <a class="channel-item active" href="#">
                    <span>
                        推荐
                    </span>
                </a>
            </li>

            <li><a class="channel-item" href="#">
                <span>
                    视频
                </span>
            </a></li>
        </ul>
    </div>
    <div class="center">
        <div id="error"></div>
        <ul class="news_list">
        </ul>

        <div class="content">
            <div class="pagination-holder clearfix">
                <div id="light-pagination" class="pagination"></div>
            </div>
        </div>

        <div id="no" style="text-align: center;color: red;font-size: 20px"></div>
    </div>
</div>
</body>
<script src="js/jquery-3.3.1.js"></script>
<script src="js/jquery.simplePagination.js"></script>
<script>
    $(function () {
	    //设置加载时开始页面和页面大小
        let start = 1;
        let pageSize = 10;
        pageIn(start,pageSize);
        //查询当前页面数据的方法
        function pageIn(start,pageSize){
            $.ajax({
                url:"newsServlet02",
                data:{"start":start,"pageSize":pageSize},
                type:"POST",
                dataType:"json",
                success:function(datas){
                    if (datas.list.length == 0){
                        $("#error").html("无数据信息!");
                        return;
                    }
                    let html = ``;
                    for (let i = 0; i < datas.list.length; i++) {
                        html+=`<li>
                                    <div class="title-box">
                                        <a href="#" class="link">
                                            ${datas.list[i].title}
                                            <hr>
                                        </a>
                                    </div>
                                </li>`;
                    }
                    $(".news_list").html(html);

                    //分页
                    $("#light-pagination").pagination({
                        pages:datas.page,
                        currentPage:datas.pageNum
                    });

                    //添加分页点击事件;递归
                    $("#light-pagination .page-link").click(function () {
                        let v = $(this).html();
                        if(v == "Prev"){
                            pageIn(datas.pageNum-1,pageSize);
                        }else if(v == "Next"){
                            pageIn(datas.pageNum-1,pageSize);
                        }else {
                            pageIn(v,pageSize);
                        };
                    });
                }
            })
        }
    });
</script>
</html>
</body>
</html>

后端与瀑布式一样
servlet改变处

//2.根据当前页码和每页显示的条数,调用业务层的方法,得到分页Page对象
NewsServiceImpl newsService = new NewsServiceImpl();
Page page = newsService.pageQuery(Integer.parseInt(start), Integer.parseInt(pageSize));
//封装数据
PageInfo<List<News>> info = new PageInfo<>(page);
//3.将得到的数据转为json
String s = new ObjectMapper().writeValueAsString(info);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值