JavaWeb-Ajax

文章目录

1.基本介绍

2.应用场景

3.两种通信方式对比

1.传统web通信方式
2.Ajax通信方式

4.原生Ajax

1.快速入门
1.案例
2.创建maven项目,导入依赖
xml 复制代码
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.2.4</version>
    </dependency>
  </dependencies>
3.编写代码
1.User.java
java 复制代码
package entity;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class User {
    private Integer id;
    private String username;
    private String pwd;
    private String email;

    public User(Integer id, String username, String pwd, String email) {
        this.id = id;
        this.username = username;
        this.pwd = pwd;
        this.email = email;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
2.login.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
    <script type="text/javascript">
        window.onload = function () {
            //获取验证用户名按钮的dom对象
            var elementById = document.getElementById("checkButton");
            elementById.onclick = function () { //绑定点击事件
                //点击按钮之后发送ajax请求到服务器
                //创建xmlHttpRequest对象
                var xmlHttpRequest = new XMLHttpRequest();
                //由于需要验证用户名,所以先获取username的信息
                var elementById1 = document.getElementById("uname");
                var username = elementById1.value;
                //打开ajax引擎对象,放入username的数据
                //第一个参数是请求方式,第二个是url,第三个是开启异步
                xmlHttpRequest.open("get", "/ajax/checkUserServlet" + "?uname=" +username, true);

                //在send之前,给ajax引擎对象绑定一个事件,当引擎对象的onreadystate变化时就会触发
                //初始发送成功是2,请求处理中是3,请求已完成且响应已就绪是4,也就是会改变两次,触发两次事件
                xmlHttpRequest.onreadystatechange = function () {
                    if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
                        //判断是否请求已完成且响应已就绪,并且响应码是200
                        var responseText = xmlHttpRequest.responseText; //获取响应的信息
                        //得到要填入信息的input
                        var elementById2 = document.getElementById("myres");
                        if (responseText != "") {
                            elementById2.value = "用户名可用"
                        }
                        else {
                            elementById2.value = "用户名不可用"
                        }
                        //把返回的json数据显示在div,实现局部刷新
                        var elementById3 = document.getElementById("div1");
                        elementById3.innerText = responseText;

                    }
                }

                //发送,如果是get请求则直接发送,如果是post请求,则在里面放入内容
                xmlHttpRequest.send();

            }
        }
    </script>
</head>
<body>
<h1>用户注册</h1>
<form action="/ajax/checkUserServlet" method="post">
    用户名字:<input type="text" name="username" id="uname">
    <input type="button" id="checkButton" value="验证用户名">
    <input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>
    用户密码:<input type="password" name="password"><br/><br/>
    电子邮件:<input type="text" name="email"><br/><br/>
    <input type="submit" value="用户注册">
</form>
<h1>返回的json数据</h1>
<div id="div1"></div>
</body>
</html>
3.CheckUserServlet.java
java 复制代码
package servlet;

import com.google.gson.Gson;
import entity.User;

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;

/**
 * @author 孙显圣
 * @version 1.0
 */
@WebServlet("/checkUserServlet")
public class CheckUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uname = req.getParameter("uname");

        if ("king".equals(uname)) { //如果用户是king,将用户信息使用json的形式发送到前端
            User king = new User(1, "king", "123456", "1721469477@qq.com");
            //转换成json字符串
            String json = new Gson().toJson(king);
            //设置编码
            resp.setContentType("text/html;charset=utf-8");
            //返回
            resp.getWriter().print(json);
        }
        else {
            //返回空
            resp.getWriter().print("");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
4.结果
4.后置资料
5.课后作业------接入DB
1.导入依赖
xml 复制代码
    <dependency>
      <groupId>commons-dbutils</groupId>
      <artifactId>commons-dbutils</artifactId>
      <version>1.3</version>
    </dependency>
    <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <version>8.0.32</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.10</version>
    </dependency>
2.创建德鲁伊连接池配置文件src/druid.properties
properties 复制代码
#key=value
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/hsp_db02?rewriteBatchedStatements=true
#url=jdbc:mysql://localhost:3306/girls
username=root
password=root
#initial connection Size
initialSize=10
#min idle connecton size
minIdle=5
#max active connection size
maxActive=50
#max wait time (5000 mil seconds)
maxWait=5000
3.创建德鲁伊工具类java/utils/JDBCUtilsByDruid.java
java 复制代码
package utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class JDBCUtilsByDruid {
    //静态数据源引用(jdbc的接口)
    private static DataSource dataSource;

    //静态代码块,在类加载时为数据源引用赋值
    static {
        //1.读取配置文件
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src\\druid.properties"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //2.使用配置文件,创建德鲁伊数据源对象
        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //编写getConnection方法
    public static Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //把Connection对象放回连接池
    public static void close(ResultSet resultSet, Statement statement, Connection connection) {
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }


}
4.创建java/BasicDao_/BasicDao.java
java 复制代码
package BasicDao_;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import utils.JDBCUtilsByDruid;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class BasicDao<T> { //泛型指定具体类型
    //获取QueryRunner,用于执行crud语句
    private QueryRunner qr = new QueryRunner();

    //开发通用的dml方法
    public int update(String sql, Object... parameters) { //返回影响的行数
        //获取连接
        Connection connection = null;

        try {
            connection = JDBCUtilsByDruid.getConnection();
            int update = qr.update(connection, sql, parameters);
            return update;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭资源
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }

    //返回多个对象,即查询的结果是多行的
    /**
     * @param sql:传入sql语句
     * @param clazz:传入一个类的Class对象,类型由泛型决定,这个类型是要封装到的javabean类型
     * @param parameters:传入填充sql的参数
     * @return 根据Class类型返回对应的ArrayList集合
     */
    public List<T> queryMulti(String sql, Class<T> clazz, Object... parameters) {
        //获取连接
        Connection connection = null;

        try {
            connection = JDBCUtilsByDruid.getConnection();
            List<T> query = qr.query(connection, sql, new BeanListHandler<T>(clazz), parameters);
            return query;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭资源
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }

    //查询单行的结果的通用方法
    public T querySingle(String sql, Class<T> clazz, Object... parameters) {
        //获取连接
        Connection connection = null;

        try {
            connection = JDBCUtilsByDruid.getConnection();
            T query = qr.query(connection, sql, new BeanHandler<T>(clazz), parameters);
            return query;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭资源
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }

    //查询单行单列的方法
    public Object queryScalar(String sql, Object... parameters) {
        //获取连接
        Connection connection = null;

        try {
            connection = JDBCUtilsByDruid.getConnection();
            Object query = qr.query(connection, sql, new ScalarHandler(), parameters);
            return query;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }

    }

}
5.数据表设计
sql 复制代码
CREATE TABLE `user`(
		id INT PRIMARY KEY AUTO_INCREMENT,
		username VARCHAR(32) NOT NULL DEFAULT(''),
		pwd VARCHAR(32) NOT NULL DEFAULT(''),
		email VARCHAR(32) NOT NULL DEFAULT('')
);

INSERT INTO user VALUES(NULL, 'king', '123456', '1721469477@qq.com');
6.表的映射类java/entity/User.java

注意一定要添加无参构造

java 复制代码
package entity;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class User {
    private Integer id;
    private String username;
    private String pwd;
    private String email;
    //无参构造!!
    public User() {

    }

    public User(Integer id, String username, String pwd, String email) {
        this.id = id;
        this.username = username;
        this.pwd = pwd;
        this.email = email;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", pwd='" + pwd + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}
7.java/dao/UserDao.java
java 复制代码
package dao;

import BasicDao_.BasicDao;
import entity.User;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class UserDao extends BasicDao<User> {
}
8.测试使用
java 复制代码
import dao.UserDao;
import entity.User;
import org.junit.Test;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class test {
    @Test
    public void testSelect() {
        UserDao userDao = new UserDao();
        //测试查询
        User user = userDao.querySingle("select * from user where id = ?", User.class, 1);
        System.out.println(user);

    }

}
9.注意:在maven项目下读取properties配置文件
  1. 前面是在javase 环境下读取的properties配置文件,如果是在maven项目下,应该将properties配置文件放在resources下,使用类加载器读取
  2. 修改JDBCUtilsByDruid
  3. 更改配置文件druid.properties位置
10.login.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
    <script type="text/javascript">
        window.onload = function () {
            //获取验证用户名按钮的dom对象
            var elementById = document.getElementById("checkButton");
            elementById.onclick = function () { //绑定点击事件
                //点击按钮之后发送ajax请求到服务器
                //创建xmlHttpRequest对象
                var xmlHttpRequest = new XMLHttpRequest();
                //由于需要验证用户名,所以先获取username的信息
                var elementById1 = document.getElementById("uname");
                var username = elementById1.value;
                //打开ajax引擎对象,放入username的数据
                //第一个参数是请求方式,第二个是url,第三个是开启异步
                xmlHttpRequest.open("get", "/ajax/checkUserServlet" + "?uname=" +username, true);

                //在send之前,给ajax引擎对象绑定一个事件,当引擎对象的onreadystate变化时就会触发
                //初始发送成功是2,请求处理中是3,请求已完成且响应已就绪是4,也就是会改变两次,触发两次事件
                xmlHttpRequest.onreadystatechange = function () {
                    if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
                        //判断是否请求已完成且响应已就绪,并且响应码是200
                        var responseText = xmlHttpRequest.responseText; //获取响应的信息
                        //得到要填入信息的input
                        var elementById2 = document.getElementById("myres");
                        if (responseText != "") {
                            elementById2.value = "用户名可用"
                        }
                        else {
                            elementById2.value = "用户名不可用"
                        }
                        //把返回的json数据显示在div,实现局部刷新
                        var elementById3 = document.getElementById("div1");
                        elementById3.innerText = responseText;
                    }
                }

                //发送,如果是get请求则直接发送,如果是post请求,则在里面放入内容
                xmlHttpRequest.send();

            }
        }
    </script>
</head>
<body>
<h1>用户注册</h1>
<form action="/ajax/checkUserServlet" method="post">
    用户名字:<input type="text" name="username" id="uname">
    <input type="button" id="checkButton" value="验证用户名">
    <input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>
    用户密码:<input type="password" name="password"><br/><br/>
    电子邮件:<input type="text" name="email"><br/><br/>
    <input type="submit" value="用户注册">
</form>
<h1>返回的json数据</h1>
<div id="div1"></div>
</body>
</html>
11.UserService.java
java 复制代码
package service;

import dao.UserDao;
import entity.User;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class UserService {
    private UserDao userDao = new UserDao();
    public User getUserByName(String username) {
        User user = userDao.querySingle("select * from `user` where username=?", User.class, username);
        return user;
    }
}
12.CheckUserServlet.java
java 复制代码
package servlet;

import com.google.gson.Gson;
import dao.UserDao;
import entity.User;
import org.junit.Test;
import service.UserService;

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;

/**
 * @author 孙显圣
 * @version 1.0
 */
@WebServlet("/checkUserServlet")
public class CheckUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uname = req.getParameter("uname");
        //根据姓名从数据库查询
        UserService userService = new UserService();
        User user = userService.getUserByName(uname);
        if (user != null) {
            //如果查询到了信息则将用户信息使用json的形式发送到前端
            Gson gson = new Gson();
            String json = gson.toJson(user);
            resp.setContentType("text/html;charset=utf-8");
            resp.getWriter().print(json);
        }
        else {
            resp.getWriter().print("");
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
13.结果
14.完整文件目录

5.jQuery操作Ajax

1.原生Ajax请求问题分析
2.Ajax函数基本介绍
3.jQuery $.ajax应用实例(在前面项目基础上)
1.login2.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>用户注册</title>
  <script type="text/javascript" src="./jquery-3.6.0.min.js"></script>
  <script type="text/javascript">
    $(function () {
      //给按钮绑定事件
      $("#btn1").click(function () {
        //使用$.ajax({})方法向服务器发送请求
        $.ajax({
          url: "/ajax/checkUserServlet2",
          type: "get",
          data: {
            username: $("#uname").val(),
            date: new Date()
          },
          success: function (data, status, xhr) {
            console.log("成功")
            console.log("data=" , data)
            console.log("status=" + status)
            console.log("xhr=" , xhr)
            //对返回的结果进行处理
            //绑定显示信息的按钮和div
            var $myres = $("#myres");
            var $div1 = $("#div1");
            if (data.id == -1) { //说明数据不在数据库中
              $myres.val("用户不可用!")
            }
            else { //用户在数据库中
              $myres.val("用户可用!")
              //在div显示数据,需要将json对象转换成字符串
              $div1.text(JSON.stringify(data))
            }
          },
          error: function () {
            console.log("失败")
          },
          dataType: "json"
        })
      })
    })
  </script>
</head>
<body>
<h1>用户注册-jQuery + Ajax</h1>
<form action="/ajax/checkUserServlet2" method="post">
  用户名字:<input type="text" name="username" id="uname">
  <input type="button" id="btn1" value="验证用户名">
  <input style="border-width: 0;color: red" type="text" id="myres"><br/><br/>
  用户密码:<input type="password" name="password"><br/><br/>
  电子邮件:<input type="text" name="email"><br/><br/>
  <input type="submit" value="用户注册">
</form>
<h1>返回的json数据</h1>
<div id="div1"></div>
</body>
</html>
2.checkUserServlet2.java
java 复制代码
package service;

import com.google.gson.Gson;
import entity.User;

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;

/**
 * @author 孙显圣
 * @version 1.0
 */
@WebServlet("/checkUserServlet2")
public class CheckUserServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        System.out.println(username);
        //从数据库中查找信息,如果查到则以json格式响应信息
        User user = new UserService().getUserByName(username);
        //设置返回类型为json
        resp.setContentType("text/json;charset=utf-8");
        Gson gson = new Gson();
        if (user != null) {
            //返回信息
            resp.getWriter().print(gson.toJson(user));
        } else {
            User user1 = new User(-1, "", "", "");
            //返回信息
            resp.getWriter().print(gson.toJson(user1));
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
4.jQuery $.get应用实例
1.注意参数的顺序
2.代码实例
js 复制代码
        //使用$.get()方法
        $.get(
                "/ajax/checkUserServlet2",
                {
                  username: $("#uname").val(),
                  date: new Date()
                },
                function (data, status, xhr) {
                  console.log("get成功")
                  console.log("data=" , data)
                  console.log("status=" + status)
                  console.log("xhr=" , xhr)
                  //对返回的结果进行处理
                  //绑定显示信息的按钮和div
                  var $myres = $("#myres");
                  var $div1 = $("#div1");
                  if (data.id == -1) { //说明数据不在数据库中
                    $myres.val("用户不可用!")
                  }
                  else { //用户在数据库中
                    $myres.val("用户可用!")
                    //在div显示数据,需要将json对象转换成字符串
                    $div1.text(JSON.stringify(data))
                  }
                },
                "json",
        )
5.jQuery $.post应用实例
1.get和post的调用方式是一样的
2.代码实例
js 复制代码
        $.post(
                "/ajax/checkUserServlet2",
                {
                  username: $("#uname").val(),
                  date: new Date()
                },
                function (data, status, xhr) {
                  console.log("post成功")
                  console.log("data=" , data)
                  console.log("status=" + status)
                  console.log("xhr=" , xhr)
                  //对返回的结果进行处理
                  //绑定显示信息的按钮和div
                  var $myres = $("#myres");
                  var $div1 = $("#div1");
                  if (data.id == -1) { //说明数据不在数据库中
                    $myres.val("用户不可用!")
                  }
                  else { //用户在数据库中
                    $myres.val("用户可用!")
                    //在div显示数据,需要将json对象转换成字符串
                    $div1.text(JSON.stringify(data))
                  }
                },
                "json",
        )
6.jQuery $.getJSON应用实例
1.如果是get请求,并且要求响应的是json类型,则直接使用getJSON函数即可,只有三个参数url、data、回调函数
2.代码实例
js 复制代码
        //注意:这样返回的对象就是json对象,会自动将java中的json字符串转换成json对象
        $.getJSON(
                "/ajax/checkUserServlet2",
                {
                  username: $("#uname").val(),
                  date: new Date()
                },
                function (data, status, xhr) {
                  console.log("getJSON成功")
                  console.log("data=" , data)
                  console.log("status=" + status)
                  console.log("xhr=" , xhr)
                  //对返回的结果进行处理
                  //绑定显示信息的按钮和div
                  var $myres = $("#myres");
                  var $div1 = $("#div1");
                  if (data.id == -1) { //说明数据不在数据库中
                    $myres.val("用户不可用!")
                  }
                  else { //用户在数据库中
                    $myres.val("用户可用!")
                    //在div显示数据,需要将json对象转换成字符串
                    $div1.text(JSON.stringify(data))
                  }
                },
        )

6.JSON与Ajax小结

1.关于java中的JSON
1.JSON中的key都是String
2.一个javabean,map都是一个JSON对象
  1. javabean的属性是key,值是value
  2. map就是key,value格式的
3.list是一个数组
  1. 如果里面是javabean对象,就是一个JSON对象数组
  2. 如果是普通的元素就是普通数组
4.关于value在java中可以选择的类型
  • String
  • Number
  • Boolean
  • Object
2.关于JQuery操作Ajax
使用$.getJSON,会将java中返回的json字符串自动转换为json对象返回
js 复制代码
            //用户名绑定失去焦点事件
            $("#username").blur(function () {
                //获取信息,并向后端发送ajax请求
                var username = $(this).val();
                $.getJSON(
                    "memberServlet",
                    {
                        "action": "isExistName",
                        "username": username
                    },
                    function (data, status, xhr) {
                        //根据是否存在显示信息
                        if (data.isExist) {
                            $("span.errorMsg").text("用户名已存在!");
                        } else {
                            $("span.errorMsg").text("用户名可用!");
                        }
                    }
                )
            })
相关推荐
浮华似水几秒前
Javascirpt时区——脱坑指南
前端
王二端茶倒水3 分钟前
大龄程序员兼职跑外卖第五周之亲身感悟
前端·后端·程序员
_oP_i8 分钟前
Web 与 Unity 之间的交互
前端·unity·交互
钢铁小狗侠10 分钟前
前端(1)——快速入门HTML
前端·html
凹凸曼打不赢小怪兽36 分钟前
react 受控组件和非受控组件
前端·javascript·react.js
狂奔solar1 小时前
分享个好玩的,在k8s上部署web版macos
前端·macos·kubernetes
qiyi.sky1 小时前
JavaWeb——Web入门(8/9)- Tomcat:基本使用(下载与安装、目录结构介绍、启动与关闭、可能出现的问题及解决方案、总结)
java·前端·笔记·学习·tomcat
清云随笔1 小时前
axios 实现 无感刷新方案
前端
鑫宝Code1 小时前
【React】状态管理之Redux
前端·react.js·前端框架
忠实米线1 小时前
使用pdf-lib.js实现pdf添加自定义水印功能
前端·javascript·pdf