用后端实现一个简单的登录模块2 前端页面
该模块能做到的功能:
1阶:输入账号和密码,输入正确即可返回登录成功的信息,反之则登录失败
2阶:有简单的前端页面,有登录成功和失败的弹窗,还有登录成功的主页面
3阶:前端页面的注册也可以使用,注册完的帐号能直接登录
1阶结束了,咱们2阶继续
把前端页面写一下
前端登录、注册页面预览图,登录成功或失败上方会有浏览器窗口提示

前端借鉴了一下这个的视频的页面
https://www.bilibili.com/video/BV1zD4y1D7y4/%EF%BC%9Fshare_source=copy_web&vd_source=21f3fc7e7628e67cf8020c7bc3880a85视频演示源码,源自视频的简介
https://blog.csdn.net/NpcCat/article/details/106434653?spm=1001.2014.3001.5501
上面的链接只是标明原出处,不影响接下来的步骤
在resources包里新建static包,在里面新建一个file文件,命名login.html,没错这是一个html文件
再添加一个file文件,命名home.html,这两个页面分别是登录页面和登录后的主页面
login.html
样式借鉴自上面的第一个链接视频
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.6.8/axios.js"></script>
</head>
<body>
<div class="control"><div class="item"><div class="active">登录</div>
<!-- <div>注册</div>--></div><div class="content"><div style="display: block;"><p>账号</p><input type="text" id="name"/><p>密码</p><input type="password" id="password"/><br/><input type="submit" value="登录" id="btn"/></div>
<!-- <div>-->
<!-- <p>账号</p>-->
<!-- <input type="text" placeholder="请输入11位手机号" id="rename" />-->
<!-- <p>密码</p>-->
<!-- <input type="password" placeholder="请输入至少7位同时带字母和数字的密码" id="repassword" />-->
<!-- <br/>-->
<!-- <input type="submit" value="注册" id="reg"/>-->
<!-- </div>--></div>
</div><script>window.onload = function(){var item = document.getElementsByClassName("item");var it = item[0].getElementsByTagName("div");var content = document.getElementsByClassName("content");var con = content[0].getElementsByTagName("div");for(let i=0;i<it.length;i++){it[i].onclick = function(){for(let j=0;j<it.length;j++){it[j].className = '';con[j].style.display = "none";}this.className = "active";it[i].index=i;con[i].style.display = "block";}}}var btn = document.getElementById("btn")btn.onclick = function () {const user = {name:document.getElementById("name").value,password:document.getElementById("password").value}axios.post("http://localhost:8080/doLogin",user).then(res => {if(res.data.code == 200){location.href="home.html"localStorage.setItem("name",res.data.data.name);localStorage.setItem("password",res.data.data.password);alert("登录成功,欢迎:"+ res.data.data.name)}else {alert("登录失败")}})}// var reg = document.getElementById("reg")// reg.onclick = function () {// const user = {// name:document.getElementById("rename").value,// password:document.getElementById("repassword").value// }// var re=/^1\d{10}$/;// var pw= new RegExp("^(?=.{7,})(((?=.*[A-Z])|(?=.*[a-z]))(?=.*[0-9])).*$", "g");// if (re.test(user.name) && pw.test(user.password)){// axios.post("http://localhost:8080/register",user)// .then(res => {// if(res.data.code == 200){// alert("注册成功")// }// else {// alert("注册失败")// }// })}// else {// alert("手机号或密码格式不正确");// }// }
</script></body><style>*{margin: 0;padding: 0;}body{background: #f3f3f3;}.control{width: 340px;background: white;position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);border-radius: 5px;}.item{width: 340px;height: 60px;background: #eeeeee;}.item div{width: 170px;height: 60px;display: inline-block;color: black;font-size: 18px;text-align: center;line-height: 60px;cursor: pointer;}.content{width: 100%;}.content div{margin: 20px 30px;display: none;text-align: left;}p{color: #4a4a4a;margin-top: 30px;margin-bottom: 6px;font-size: 15px;}.content input[type="text"], .content input[type="password"]{width: 100%;height: 40px;border-radius: 3px;border: 1px solid #adadad;padding: 0 10px;box-sizing: border-box;}.content input[type="submit"]{margin-top: 40px;width: 100%;height: 40px;border-radius: 5px;color: white;border: 1px solid #adadad;background: #00dd60;cursor: pointer;letter-spacing: 4px;margin-bottom: 40px;}.active{background: white;}.item div:hover{background: #f6f6f6;}
</style>
</html>
前端的登录相对于注册讲的能轻松一些:
点击登录后,前端会将我们输入的账号密码放在一个叫user的对象里,然后使用post方法带着user将url传给后端,根据后端返回来的数据来确定是登录成功还是失败。
这里一共有三处被注掉的代码,这些是用来写注册功能的,现在用不上。
等说到注册功能咱再解开就可以,如果你现在就想解开也没事,不影响接下来代码的运行。
解除/添加批注快捷键:选中全部批注或需要批注的代码, ctrl+/
home.html
这是一个简单的主页面,毕竟咱主要写的是后端,前端凑合能看就行
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.6.8/axios.js"></script>
</head>
<body>
<div class="control"><div class="item"><div class="active">这是主页面</div></div><div class="content"><div style="display: block;"><input type="submit" value="退出登录" id="btn"/></div></div>
</div>
</body><script>window.onload = function(){let name = localStorage.getItem("name");let password = localStorage.getItem("password");if (name == null || password == null){location.href="login.html"alert("请先登录")}const user = {name:name,password:password}axios.post("http://localhost:8080/doLogin",user).then(res => {if(res.data.code != 200){location.href="login.html"alert("请先登录")}})var item = document.getElementsByClassName("item");var it = item[0].getElementsByTagName("div");var content = document.getElementsByClassName("content");var con = content[0].getElementsByTagName("div");for(let i=0;i<it.length;i++){it[i].onclick = function(){for(let j=0;j<it.length;j++){it[j].className = '';con[j].style.display = "none";}this.className = "active";it[i].index=i;con[i].style.display = "block";}}}var btn = document.getElementById("btn")btn.onclick = function () {localStorage.removeItem("name");localStorage.removeItem("password");location.href = "login.html"}</script><style>*{margin: 0;padding: 0;}body{background: #f3f3f3;}.control{width: 340px;background: white;position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);border-radius: 5px;}.item{width: 340px;height: 60px;background: #eeeeee;}.item div{width: 340px;height: 60px;display: inline-block;color: black;font-size: 18px;text-align: center;line-height: 60px;cursor: pointer;}.content{width: 100%;}.content div{margin: 20px 30px;display: none;text-align: left;}p{color: #4a4a4a;margin-top: 30px;margin-bottom: 6px;font-size: 15px;}.content input[type="text"], .content input[type="password"]{width: 100%;height: 40px;border-radius: 3px;border: 1px solid #adadad;padding: 0 10px;box-sizing: border-box;}.content input[type="submit"]{margin-top: 40px;width: 100%;height: 40px;border-radius: 5px;color: white;border: 1px solid #adadad;background: #00dd60;cursor: pointer;letter-spacing: 4px;margin-bottom: 40px;}.active{background: white;}.item div:hover{background: #f6f6f6;}
</style>
</html>
这里加了个本地存储,如果在登录界面登录成功,前端会把输入正确的账号和密码的键和值保存在浏览器。这样就能保证主页面只有在登录状态下才能正常显示,否则(运行后端后直接通过home.html 右上角的浏览器图标直接进入主页面)会弹回登录界面。
| 键 | 值 |
| name | 13334455667 |
| password | 123456q |
相关文章:
用后端实现一个简单的登录模块2 前端页面
该模块能做到的功能: 1阶:输入账号和密码,输入正确即可返回登录成功的信息,反之则登录失败 2阶:有简单的前端页面,有登录成功和失败的弹窗,还有登录成功的主页面 3阶:前端页面的注…...
MySQL慢查询的查找语法
一、引言 数据库查询快慢是影响项目性能的一大因素,对于数据库,我们除了要优化SQL,更重要的是得先找到需要优化的SQL语句。 性能优化的思路 首先需要使用慢查询功能,去获取所有查询时间比较长的SQL语句其次使用explain命令去查…...
SQL中的聚合方法与Pandas的对应关系
在SQL和Pandas中,聚合方法是用来对数据进行汇总统计的重要工具。下面是SQL中的各种聚合方法及其与Pandas中相应操作的对应关系: 1. COUNT SQL: COUNT(*) 返回表中的行数。COUNT(column) 返回指定列中非空值的数量。 Pandas: count() 方法用于计算非空值…...
计算机毕业设计选题推荐-计算中心高性能集群共享平台-Java/Python项目实战
✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...
仿RabbitMq实现简易消息队列基础篇(future操作实现异步线程池)
TOC 介绍 std::future 是C11标准库中的一个模板类,他表示一个异步操作的结果,当我们在多线程编程中使用异步任务时,std::future可以帮助我们在需要的时候,获取任务的执行结果,std::future 的一个重要特性是能…...
经典算法题总结:数组常用技巧(双指针,二分查找和位运算)篇
双指针 在处理数组和链表相关问题时,双指针技巧是经常用到的,双指针技巧主要分为两类:左右指针和快慢指针。所谓左右指针,就是两个指针相向而行或者相背而行;而所谓快慢指针,就是两个指针同向而行…...
版本控制基础理论
一、本地版本控制 在本地记录文件每次的更新,可以对每个版本做一个快照,或是记录补丁文件,适合个人使用,如RCS. 二、集中式版本控制(代表SVN) 所有的版本数据都保存在服务器上,协同开发者从…...
微分方程(Blanchard Differential Equations 4th)中文版Section1.4
1.4 NUMERICAL TECHNIQUE: EULER’S METHOD 上一节中讨论的斜率场的几何概念与近似微分方程解的基本数值方法密切相关。给定一个初值问题 d y d t = f ( t , y ) , y ( t 0 ) = y 0 , \frac{dy}{dt}=f(t,y), \quad y(t_0) = y_0, dtdy=f(t,y),y(t0)=y0, 我们可以通过首…...
求职Leetcode算法题(7)
1.搜索旋转排序数组 这道题要求时间复杂度为o(log n),那么第一时间想到的就是二分法,二分法有个前提条件是在有序数组下,我们发现在这个数组中存在两部分是有序的,所以我们只需要对前半部分和后半部分分别…...
ActiveMQ、RabbitMQ、Kafka、RocketMQ在事务性消息、性能、高可用和容错、定时消息、负载均衡、刷盘策略的区别
ActiveMQ、RabbitMQ、Kafka、RocketMQ这四种消息队列在事务性消息、性能、高可用和容错、定时消息、负载均衡、刷盘策略等方面各有其特点和差异。以下是对这些方面的详细比较: 1. 事务性消息 ActiveMQ:支持事务性消息。ActiveMQ可以基于JMS(…...
HanLP分词的使用与注意事项
1 概述 HanLP是一个自然语言处理工具包,它提供的主要功能如下: 分词转化为拼音繁转简、简转繁提取关键词提取短语提取词语自动摘要依存文法分析 下面将介绍其分词功能的使用。 2 依赖 下面是依赖的jar包。 <dependency><groupId>com.ha…...
Python 的进程、线程、协程的区别和联系是什么?
一、区别 1. 进程 • 定义:进程是操作系统分配资源的基本单位。 • 资源独立性:每个进程都有独立的内存空间,包括代码、数据和运行时的环境。 • 并发性:可以同时运行多个进程,操作系统通过时间片轮转等方式在不同…...
实时数据推送:Spring Boot 中两种 SSE 实战方案
在 Web 开发中,实时数据交互变得越来越普遍。无论是股票价格的波动、比赛比分的更新,还是聊天消息的传递,都需要服务器能够及时地将数据推送给客户端。传统的 HTTP 请求-响应模式在处理这类需求时显得力不从心,而服务器推送事件&a…...
数据守护者:SQL一致性检查的艺术与实践
标题:数据守护者:SQL一致性检查的艺术与实践 在数据驱动的商业世界中,数据的一致性是确保决策准确性和业务流程顺畅的关键。SQL作为数据查询和操作的基石,提供了多种工具来维护数据的一致性。本文将深入探讨如何使用SQL进行数据一…...
jenkins配置+vue打包多环境切换
jenkins配置流水线过程 1.新建item 加入相关的参数就行了。 流水线脚本设置 后端脚本 node {stage checkoutsh"""#每次打包清空工作空间目录rm -rf $workspace/*cd $workspace#到工作空间下从远端svn服务端拉取代码svn co svn://10.1.19.21/repo/技术中台/低…...
idea和jdk的安装教程
1.JDK的安装 下载 进入官网,找到你需要的JDK版本 Java Downloads | Oracle 中国 我这里是windows的jdk17,选择以下 安装 点击下一步,安装完成 配置环境变量 打开查看高级系统设置 在系统变量中添加两个配置 一个变量名是 JAVA_HOME …...
HTML静态网页成品作业(HTML+CSS)——电影网首页网页设计制作(1个页面)
🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有1个页面。 二、作品演示 三、代…...
大数据系列之:Flink Doris Connector,实时同步数据到Doris数据库
大数据系列之:Flink Doris Connector,实时同步数据到Doris数据库 一、版本兼容性二、使用三、Flink SQL四、DataStream五、Lookup Join六、配置通用配置项接收器配置项查找Join配置项 七、Doris 和 Flink 列类型映射八、使用Flink CDC访问Doris的示例九、…...
LabVIEW VI 多语言动态加载与运行的实现
在多语言应用程序开发中,确保用户界面能够根据用户的语言偏好动态切换是一个关键需求。本文通过分析一个LabVIEW程序框图,详细说明了如何使用LabVIEW中的属性节点和调用节点来实现VI(虚拟仪器)界面语言的动态加载与运行。此程序允…...
Unity引擎基础知识
目录 Unity基础知识概要 1. 创建工程 2. 工程目录介绍 3. Unity界面和五大面板 4. 游戏物体创建与操作 5. 场景和层管理 6. 组件系统 7. 脚本语言C# 8. 物理引擎和UI系统 学习资源推荐 Unity引擎中如何优化大型游戏项目的性能? Unity C#脚本语言的高级编…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
