当前位置: 首页 > news >正文

专业的免费网站建设哪家叮当app制作官网

专业的免费网站建设哪家,叮当app制作官网,想让网站被谷歌收录怎么做,科技进化论文章目录1. 创建项目2. 数据库设计3. 前置任务3.1 拦截器3.2 统一数据格式3.3 创建一个 Constant3.4 统一异常处理3.5 密码加密4. 功能实现4.1 登录功能4.2 注册功能4.3 博客列表页 #xff08;功能实现#xff09;4.3.1 左侧框4.3.2 右侧框 (分页功能 页面显示)4.4 博客详情… 文章目录1. 创建项目2. 数据库设计3. 前置任务3.1 拦截器3.2 统一数据格式3.3 创建一个 Constant3.4 统一异常处理3.5 密码加密4. 功能实现4.1 登录功能4.2 注册功能4.3 博客列表页 功能实现4.3.1 左侧框4.3.2 右侧框 (分页功能 页面显示)4.4 博客详情页4.5 写博客功能4.6 注销功能博客系统 前言 本文主要 是通过 ssm 搭配之前的 博客系统页面 来完成一个小项目 . 项目完整代码 1. 创建项目 使用到的技术 后端 Spring Boot Spring MVC MyBatis 拦截器 / 统一异常处理 统一数据返回 (Spring AOP)前端 : HTML CSS javaScript jquery 2. 数据库设计 通过我们需要实现的功能 能够知道 需要两张表 第一张表 用户表 用来完成登录 注册 注销等功能 第二张表 用来存储 博客 查看博客等 . 1. 创建 用户列表 -- 如果存在 这个数据库就删除drop database if exits mywebsite;-- 创建数据库create database mywebsite;-- 选中数据库 use mywebsite-- 创建用户表create table user ( -- 系统分配id int primary key auto_increment, -- 必填username varchar(255) not null,password varchar(255) not null, -- 非必填qq varchar(255) default ,address varchar(255) default ,crateTime datetime default now(),sex varchar(2) default 男, -- url 用来存放 用户 头像 图片 如果用户没有上传就使用默认的 .url varchar(1024) default 阳台.png );2. 创建 blog 表 create table blog (blogId int primary key auto_increment,title varchar(1024) not null,-- 这里 一篇博客的内容可能非常多 使用 varchar可能不够 这里就是用 mediumtextcontent mediumtext,-- 用户 iduserid int,-- 发布时间postTime datetime default now(),-- 类型type varchar(255) not null, );表创建好了 下面就可以完成一些 准备工作 比如 配置好环境 写好 拦截器 统一数据格式 等 . 这里统一数据格式 可以写一个类 通过这个类来返回 或者 通过 ControllerAdvice ResponseBodyAdvice 来完成 这里我会使用 写一个类来返回信息 . 3. 前置任务 这里先来完成 拦截器 统一异常处理 统一数据格式 . application.yml # 配置当前运行的环境 (配置文件)# spring profiles active spring:profiles:active: dev # 使用开发环境的配置文件# 配置 mybatis xml 保存路径 mybatis:mapper-locations: classpath:mybatis/**Mapper.xml# 在公共 yml 文件 来 配置 mybatis 的保存路径 application-dev.yml # 开发环境的配置文件spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mywebsite?characterEncodingutf8username: rootpassword: 1234driver-class-name: com.mysql.cj.jdbc.Driver # 在 8.0 之前 是没有点 jc的 - com.mysql.jdbc.Driver# 设置日志级别 logging:level:com:example:usermanager: debug# 对具体类机型日志级别设定# 开启 MyBatis SQL 打印 mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl3.1 拦截器 这里我们实现拦截器 主要有两部 1. 自定义拦截器 2. 给拦截器设置规则 (那些 需要拦截 那些不需要拦截) 附上代码 AppConfig 类 package com.example.usermanager.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 系统配置文件*/Configuration public class AppConfig implements WebMvcConfigurer {// 注入拦截器Autowiredprivate LoginIntercept loginIntercept;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginIntercept).addPathPatterns(/**).excludePathPatterns(/user/login).excludePathPatterns(/insert).excludePathPatterns(/css/**).excludePathPatterns(/fonts/**).excludePathPatterns(/images/**).excludePathPatterns(/js/**).excludePathPatterns(/login.html);} } LoginIntercept package com.example.blog_ssm.config;import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;/*** 自定义拦截器*/Component public class LoginIntercept implements HandlerInterceptor {/*** true 表示已经登录 会继续访问目标方法* false 表示未登录 跳转到登录页面*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// false : 如果 没有 session 也不会创建HttpSession session request.getSession(false);if (session ! null session.getAttribute(user) ! null) {// 表示登录成功return true;}// 403 当前你没有资格访问response.setStatus(403);// 重定向response.sendRedirect(/login.html);return false;} } 拦截器 弄好了 我们可以看看效果 : xml 配置文件 ?xml version1.0 encodingUTF-8? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.example.blog_ssm.mapper.UserMapper/mapper 3.2 统一数据格式 1. 创建一个类用来 统一 数据格式 附上代码 package com.example.blog_ssm.util;import lombok.Data;/*** 用来统一数据格式** param T*/ Data public class ResponseBodyMessageT {// 1. 状态码private Integer status;// 2. 信息描述private String message;// 3. 数据private T data;public ResponseBodyMessage(Integer status, String message, T data) {this.status status;this.message message;this.data data;} } 2. 使用注解 3.3 创建一个 Constant 之前我们写拦截器的使用 通过 session 中的key 获取 user 对象时 写了一个 “user” 这里可以使用一个类 在类里面写一个 常量 然后 只需要通过这个 来获取 user 即可 。 3.4 统一异常处理 代码 package com.example.blog_ssm.config;import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;/*** 统一异常的拦截处理类*/RestControllerAdvice// 使用 ControllerAdvice 需要再加一个注解 ResponseBody (返回一个非静态页面)public class MyExceptionAdvice {ExceptionHandler(Exception.class)public Object exceptionAdvice(Exception e) {HashMapString, Object result new HashMap();result.put(status, -1);result.put(message, 程序异常 : e.getMessage());result.put(data, );return result;} } 3.5 密码加密 在 util 包内 创建 PasswordUtil 类 package com.example.blog_ssm.util;import cn.hutool.core.util.IdUtil; import cn.hutool.crypto.SecureUtil; import org.springframework.util.StringUtils;/*** 密码工具类*/public class PasswordUtil {/*** 1. 加密 (加盐)*/public String encrypt(String password) {// 密码 : 随机盐值 密码String salt IdUtil.simpleUUID();String finalPassword SecureUtil.md5(salt password);return salt $ finalPassword;}/*** 解密** param password 要验证的密码 (未加密)* return 数据库中的加了盐值的密码*/public boolean decrypt(String password, String securePassword) {boolean result false;if (StringUtils.hasLength(password) StringUtils.hasLength(securePassword)) {// 注意 : $ 是特殊字符 , 使用 split 分割时 需要转移if (securePassword.length() 65 securePassword.contains($)) {// 随机盐值 为 32 , md5 加密的 密码 32 加上 $ 1字符 总共 65 字符String[] securePasswordArr securePassword.split(\\$);// 盐值String salt securePasswordArr[0];// 根据盐值 加密的密码String finalPassword securePasswordArr[1];// 根据盐值 对新的密码进行加密password SecureUtil.md5(salt password);// 进行对比if (finalPassword.equals(password)) {result true;}}}return result;} } 将 工具类 交给 spring 管理 后面使用 只需要注入即可 . 到此我们就完成了前置任务 下面来写我们的功能 4. 功能实现 4.1 登录功能 约定一下 请求和响应 请求 : [{post, (登录一般使用 post)/user/login data:{username : 张三,password :1234}} ]响应 : [{status : 1 / -1 (1 表示成功 , -1 表示失败) .message : 登录成功 / 登录失败,data : true / false} ]图一 图二 此时 后端就完成了 下面就可以来写前端了 图一 图二 : 代码 !DOCTYPE html html langen headmeta charsetUTF-8title登录页面/titlelink relstylesheet href./css/common.csslink relstylesheet href./css/login.cssscript src./js/jquery.js/script /head body!-- 导航栏 -- div classnavimg src./imgs/阳台.pngspan classtitle我的博客系统/span!-- 这个标签仅仅用于占位 ,把下面几个a 标签挤到右边--div classspacer/diva href#主页/aa href#写博客/a /div!--正文部分这个 login-container 是贯穿整个页面的容器 -- div classlogin-container!-- 垂直水平居中的登录对话框 --div classlogin-dialogh3登录/h3div classrowspan用户名/spaninput typetext idusername placeholder输入用户名/divdiv classrowspan密码/spaninput typepassword idpassword placeholder输入密码/divdiv classrowbutton idsubmit提交/button/divdiv classrowa idinsert href add.html注册/a/divdiv classa没有账户 点击上面进行注册/div/div/divscript// 通过 id 选中输入框 ,let username document.querySelector(#username);// 通过 id 选中密码框let password document.querySelector(#password);let submit document.querySelector(#submit);// 点击按钮后触发submit.onclick function () {// 1. 判断 username or passwordif (jQuery.trim(username.value) ) {alert(请先输入用户名);}if (jQuery.trim(password.value) ) {alert(请先输入密码)}// 此时 用户 和密码 都有了 发送 请求$.ajax({url: /user/login,type: POST,data: {username: username.value,password: password.value},// 回调函数success: function (result) {if (result ! null result.data.status 0) {// 登录成功 , 跳转到 博客列表页location.href blog_list.html;} else {//登录 登录失败 ,alert(登录失败,请重新输入)}}})}/script/body /html登录功能搞完 下面就可以来弄 注册功能 4.2 注册功能 约定一下请求和响应 : 请求: [{post,url : /user/adddata:{必填username : xxx,password : xxx,非必填address : xxx,......}} ]响应 : [{data:{status : 1 / -1 注册成功 / 注册失败message : ,data : true / false}} ]图一 图二 图三 图四 附上代码 /*** 2. 注册功能*/RequestMapping(value /add)Transactionalpublic ResponseBodyMessageBoolean addUser(User user, RequestPart(required false, value filename) MultipartFile file) {if (user null) {return new ResponseBodyMessage(-1, 注册失败, false);}// 1. 判断 必填参数是否为空 (这里可以不写 前端大概率 是会判断的 。 )if (.equals(user.getUsername())) {return new ResponseBodyMessage(-1, 注册失败, 当前用户为输入用户名, false);}if (.equals(user.getPassword())) {return new ResponseBodyMessage(-1, 注册失败当前用户未输入密码, false);}// 2. 校验用户名的 唯一性 : 如果 用户名已经纯在了 那么就不能注册User user2 userService.getUserByUserName(user.getUsername());if (user2 ! null) {return new ResponseBodyMessage(-1, 注册失败, 用户名已存在, false);}// 3. 手动设置 为 的数据if (.equals(user.getAddress())) {user.setAddress(null);}if (.equals(user.getQq())) {user.setQq(null);}if (.equals(user.getSex())) {user.setSex(null);}if (.equals(user.getUrl())) {user.setUrl(null);}// 4. 对密码进行加密操作user.setPassword(passwordUtil.encrypt(user.getPassword()));// 5. 如果用户 上传了头像 可以将图片存入到本地if (file ! null) {// 此时上传了头像 :// 获取到文件名 类型String fileNameAndType file.getOriginalFilename();// 比如文件名为 阳台.png , 此时可以获取到 . 的 下标int index fileNameAndType.lastIndexOf(.);// 从 index 位置开始截取String postfix fileNameAndType.substring(index);// 判断一下 图片的格式是否符合预期要求if (.jpg.equals(postfix) || .png.equals(postfix)) {// 通过 uuid 来设置文件名String uuid IdUtil.simpleUUID();String imgFileStr uuid postfix;// 创建文件String path IMAGE_PATH imgFileStr;File imgFile new File(path);if (!imgFile.exists()) {imgFile.mkdir();}try { // 指定图片 , 上传之后的存储位置file.transferTo(imgFile);// 文件上传成功 :user.setUrl(imgFileStr);userService.addUser(user);return new ResponseBodyMessage(1, 注册成功, true);} catch (IOException e) { // e.printStackTrace();// 如果 创建失败 , 手动事务回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}// 此时 注册失败return new ResponseBodyMessage(-1, 注册失败, false);} else {return new ResponseBodyMessage(-1, 图片格式有误, false);}}// 6. 调用 userService 中的 addUser 方法 进行用户添加 (此时未上传图片 , 图片 为 默认)Integer ret userService.addUser(user);if (ret ! 1) {return new ResponseBodyMessage(-1, 注册失败, false);}return new ResponseBodyMessage(1, 注册成功, true);}后端写完 来完成我们的前端 : 之前并没有完成 注册页面 这里直接来拷贝一下 1. add.html !DOCTYPE html !-- 网页使用的语言 -- html langzh-CN head!-- 指定字符集 --meta charsetutf-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1title添加用户/titlelink hrefcss/bootstrap.min.css relstylesheetstylebody {background-image: url(./images/阳台.png);background-repeat: no-repeat;background-size: cover;}/style /head body div classcontainer stylewidth: 400px;h3 styletext-align: center;添加用户/h3div classform-grouplabel forloginname登录名/labelinput typetext classform-control idloginname nameusername placeholder请输入登录名//divdiv classform-grouplabel forusername姓名/labelinput typetext classform-control idusername namename placeholder请输入姓名//divdiv classform-grouplabel forpassword密码/labelinput typepassword classform-control idpassword namepassword placeholder请输入密码//divdiv classform-grouplabel forpassword2确认密码/labelinput typepassword2 classform-control idpassword2 namepassword placeholder请输入密码//divdiv classform-grouplabel性别/labelinput idman typeradio namesex value男 checkedchecked/男nbsp;nbsp;nbsp;input idwomen typeradio namesex value女/女/divdiv classform-grouplabel forage年龄/labelinput typenumber classform-control idage nameage placeholder请输入年龄//divdiv classform-grouplabel foraddress籍贯/labelselect nameaddress idaddress classform-controloption value北京北京/optionoption value上海上海/optionoption value广州广州/optionoption value深圳深圳/optionoption value成都成都/optionoption value杭州杭州/optionoption value重庆重庆/optionoption value西安西安/optionoption value武汉武汉/optionoption value沧州沧州/optionoption value江西江西/option/select/divdiv classform-grouplabel forqqQQ/labelinput typetext idqq classform-control nameqq placeholder请输入QQ号码//divdiv classform-grouplabel foremailEmail/labelinput typetext idemail classform-control nameemail placeholder请输入邮箱地址//div!-- styledisplay: none;--div classform-group idadminDivlabel foremail管理员/labelinput idadmin_yes typeradio nameisadmin value1/是nbsp;nbsp;nbsp;input idadmin_no typeradio nameisadmin value0 checkedchecked/否/divdiv classform-group styletext-align: centerinput idbtn_sub classbtn btn-primary typebutton value提交 onclickmysub()/input idbtn_back classbtn btn-default typebutton value返回 onclicklocation.hreflist.html//div/div/body /html用到的 css 可以到 我 的资源里面下载 出来 比较多 这里就不拷贝到上面 了 . 这里我们需要使用 FormData 来 发送我们的数据 可以看来看一下这 : FormData 代码 !DOCTYPE html !-- 网页使用的语言 -- html langzh-CN head!-- 指定字符集 --meta charsetutf-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1title添加用户/titlelink href./css/bootstrap.min.css relstylesheetscript src./js/jquery.js/scriptstylebody {background-image: url(./imgs/阳台.png);background-repeat: no-repeat;background-size: cover;}#image {width: 400px;height: 250px;border: 1px solid #eee;}.message {width: 110px;height: 50px;line-height: 50px;font-weight: 600;}/style /head bodyform enctypemultipart/form-data idform1div classcontainer stylewidth: 400px;h3 styletext-align: center;添加用户/h3div classform-grouplabel forusername姓名/labelinput typetext classform-control idusername namename placeholder请输入姓名//divdiv classform-grouplabel forpassword密码/labelinput typepassword classform-control idpassword namepassword placeholder请输入密码 //divdiv classform-grouplabel forpassword2确认密码/labelinput typepassword2 classform-control idpassword2 namepassword placeholder请输入密码//divdiv classform-grouplabel性别/labelinput idman typeradio namesex value男 checkedchecked/男nbsp;nbsp;nbsp;input idwomen typeradio namesex value女/女/divdiv classform-grouplabel foraddress籍贯/labelselect nameaddress idaddress classform-controloption value可以不选择/optionoption value北京北京/optionoption value上海上海/optionoption value广州广州/optionoption value深圳深圳/optionoption value成都成都/optionoption value杭州杭州/optionoption value重庆重庆/optionoption value西安西安/optionoption value武汉武汉/optionoption value沧州沧州/optionoption value江西江西/option/select/divdiv classform-grouplabel forqqQQ/labelinput typetext idqq classform-control nameqq placeholder请输入QQ号码 (非必填) //divdiv classform-groupinput typefile namefilename idimgFilespan classmessage图片样式: /spanimg src idimage//divdiv classform-group styletext-align: centerinput idbtn_sub classbtn btn-primary typebutton value提交/input idbtn_back classbtn btn-default typebutton value返回 onclicklocation.hreflist.html//div/div/form!--// 拿到 input type 为 radio 中的内容 即 获取 男 女let sex $(input[namesex]:checked).val();let address $(#address).val(); --scriptlet imgFile document.querySelector(#imgFile);// 这一部分 : 当我们上传图片后 我们的 图片样式 就会将图片显示出来imgFile.onchange function () {let img document.querySelector(#image);let image imgFile.files[0];// let formData new FormData();if (image) {// formData.append(filename, image);img.src window.URL.createObjectURL(image);}}// 当点击 提交按钮后 构造数据 通过 ajax 发送请求给后端let submit document.querySelector(#btn_sub);submit.onclick function () {let username document.querySelector(#username);let password document.querySelector(#password);let password2 document.querySelector(#password2);// 通过 jquery 拿到 性别框里面的内容let sex jQuery(input[namesex]:checked).val();let address document.querySelector(#address).value;let qq document.querySelector(#qq).value;// jQuery.trim 去掉 前后空格if (jQuery.trim(username.value) ) {alert(请先输入用户名!!)// 将焦点设置到 id 为 username 的输入 框上username.focus();return false;}if (jQuery.trim(password.value) ) {alert(请先输入密码);password.focus();return false;}if (jQuery.trim(password2.value) ) {alert(请输入确认密码);password2.focus();}if (password.value ! password2.value) {alert(两次密码不同,请重新输入)password.focus();return false;}// 使用 formData 类来返回 let formData new FormData();formData.append(username, username.value);formData.append(password, password.value);formData.append(qq, qq);formData.append(sex, sex);formData.append(address, address);let img document.querySelector(#image);// 获取文件let image imgFile.files[0];// 这里也可以通过 image 判断 if (img.src ) {console.log(未上传图片 !!! );formData.append(filename, null);} else {formData.append(filename, image)}// 通过 ajax 发送请求jQuery.ajax({type: POST,url: /user/add,data: formData,processData: false,contentType: false,success: function (result) {if (result ! null result.data.status 0) {alert(注册成功!);location.href login.html;}else {alert(注册失败)}},error : function(){alert(出错了, 请稍后再试!!!)}})}/script/body /html上传文件使用到的 input 标签 和 使用到的change 事件 input 标签 change 事件 效果 : 到此我们的注册功能就完成了 , 下面就来写我们的博客列表页 . 4.3 博客列表页 功能实现 4.3.1 左侧框 图一 AppConfig 类 package com.example.blog_ssm.config;import com.example.blog_ssm.util.PasswordUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;Configuration public class AppConfig implements WebMvcConfigurer {// 1. 注入拦截器Autowiredprivate LoginIntercept loginIntercept;Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler(/product/**).addResourceLocations(file:D:/ret/);}Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginIntercept).addPathPatterns(/**).excludePathPatterns(/user/login).excludePathPatterns(/user/add).excludePathPatterns(/css/**).excludePathPatterns(/js/**).excludePathPatterns(/imgs/**).excludePathPatterns(/login.html).excludePathPatterns(/add.html).excludePathPatterns(/product/**);}Beanpublic PasswordUtil passwordUtil() {return new PasswordUtil();} } 图二 后端完成了 下面就可以来完成我们的前端 : 图三 图四 图五 图六 : 图七 script// 这个 ajax 获取登录状态 :jQuery.ajax({type: GET,url: /user/getuser,success: function (result) {if (result ! null result.data.status 0) {let image document.querySelector(#image1);image.src product/ result.data.data.url;let image2 document.querySelector(#image2);image2.src product/ result.data.data.url;// 将用户名 换上去let username document.querySelector(#username);username.innerHTML result.data.data.username;}}})// 这个 ajax 获取 分类jQuery.ajax({type: GET,url: /blog/gettype,success: function (result) {if (result ! null result.data.status 0) {let number1 document.querySelector(#number1);let number2 document.querySelector(#number2);number1.innerHTML result.data.data[0]number2.innerHTML result.data.data[1];} else {alert(分类设置失败 !!! )}},error: function () {alert(出错了, 请稍后再试!!!)}}) /script左侧部分 就完成了 下面就来完成我们的右侧部分 这里我们可以写一个分页器 4.3.2 右侧框 (分页功能 页面显示) 图一 图二 图三 图四 这里不好截图 直接看代码 !DOCTYPE html html langen headmeta charsetUTF-8title博客列表页/titlelink relstylesheet href./css/common.csslink relstylesheet href./css/blog_list.cssscript src./js/jquery.js/scriptlink hrefcss/bootstrap.min.css relstylesheet/head body!-- 导航栏 -- div classnavimg src./imgs/阳台.png idimage1span classtitle我的博客系统/span!-- 这个标签仅仅用于占位 ,把下面几个a 标签挤到右边--div classspacer/diva href#主页/aa href#写博客/aa href#注销/a /div!-- 页面主体部分 -- div classcontainer!-- 左侧信息--div classcontainer-left!-- 使用 这个 .card 表示用户信息--div classcardimg src./imgs/girl.png alt图片显示失败 idimage2!-- 用户名--h3 idusername/h3a href#Gitee 地址/adiv classcounterspan文章/spanspan分类/span/divdiv classcounterspan idnumber11/spanspan idnumber22/span/div/div/div!-- 右侧信息--div classcontainer-right!-- lt;!ndash;--!-- 表示一篇博客--!-- ndash;gt;--!-- div classblog--!-- lt;!ndash;--!-- 博客标题--!-- ndash;gt;--!-- div classtitle我的第一篇博客/div--!-- lt;!ndash;--!-- 发布时间--!-- ndash;gt;--!-- div classdata--!-- 2023-03-02--!-- /div--!-- lt;!ndash;--!-- 博客的摘要--!-- ndash;gt;--!-- div classdesc--!-- 从今天起 , 我要认真敲代码--!-- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sint eaque facilis perferendis! Numquam--!-- neque voluptatum ab vero expedita possimus fuga eos, illo sapiente delectus quidem natus maiores,--!-- ipsum impedit rerum?--!-- /div--!-- lt;!ndash;--!-- 查看全文按钮--!-- ndash;gt;--!-- a href#查看全文 gt;gt;/a--!-- /div--div idpagenav aria-labelPage navigationul idall classpaginationli classactivea hrefjavascript:firstPage();首页/a/lilia hrefjavascript:beforePage();上一页/a/lilia hrefjavascript:nextPage();下一页/a/lilia hrefjavascript:lastPage();末页/a/lispan idpageinfo stylefont-size: 20px;margin-left: 10px;/span/ul/nav/div/div /divscript// 这个 ajax 获取登录状态 :jQuery.ajax({type: GET,url: /user/getuser,success: function (result) {if (result ! null result.data.status 0) {let image document.querySelector(#image1);image.src product/ result.data.data.url;let image2 document.querySelector(#image2);image2.src product/ result.data.data.url;// 将用户名 换上去let username document.querySelector(#username);username.innerHTML result.data.data.username;}}})// 这个 ajax 获取 分类jQuery.ajax({type: GET,url: /blog/gettype,success: function (result) {if (result ! null result.data.status 0) {let number1 document.querySelector(#number1);let number2 document.querySelector(#number2);number1.innerHTML result.data.data[0]number2.innerHTML result.data.data[1];} else {alert(分类设置失败 !!! )}},error: function () {alert(出错了, 请稍后再试!!!)}})// 分页功能 :// 1. 当前的页码let pIndex 1;// 2. 每页显示多少篇博客let pSize 2;// 3. 总页数let totalPage 0;// 4. 总条数 (当前所有的博客数目)let totalCount 0;// 通过 ajax 获取 总页数 和 总条数function getList() {jQuery.ajax({type: GET,url: /blog/listbypage,data: {pIndex: pIndex,pSize: pSize},success: function (result) {if (result ! null result.data.status 0) {// 总博客数totalCount result.data.data.count;// ceil 四舍五入并返回大于等于给定数字的最小整数。totalPage Math.ceil(parseInt(totalCount) / pSize);let size result.data.data.list.length;// rightDiv 后面创建的 元素需要挂载 rightDiv 上let rightDiv document.querySelector(.container-right);for (let i 0; i size; i) {let ret result.data.data.list[i];let blogDiv document.createElement(div);// 引入 class 属性blogDiv.className blog;// 1. 构造标题let titleDiv document.createElement(div);titleDiv.innerHTML ret.title;titleDiv.className title;// 将 titleDiv 挂到 blogDiv上blogDiv.appendChild(titleDiv);// 2. 构造 发布时间let dataDiv document.createElement(div);dataDiv.innerHTML ret.postTime;dataDiv.className data;blogDiv.appendChild(dataDiv);// 3. 构造 文章描述let descDiv document.createElement(div);descDiv.innerHTML ret.content;descDiv.className desc;blogDiv.appendChild(descDiv);// 4. 构造 查看全文按钮let a document.createElement(a);a.innerHTML 查看全文 gt;gt;;// 重点 : 这里我们点击查看全文 跳转到 博客详情页 ,这里可以 在 url 里面添加一个 博客id ,// 后面在 博客详情页就可以通过这个 blogId 获取到文章.a.href blog_detail.html?blogId ret.blogId;blogDiv.appendChild(a);rightDiv.appendChild(blogDiv);}// 将 分页器 挂载 构造好的数据 最后面 .let page document.querySelector(#page);rightDiv.appendChild(page);} else {alert(获取失败!!!)}},error: function () {alert(出错了,请稍后在尝试!!!)}})}// getList();// 首页function firstPage() {location.href blog_list.html?pIndex1}// 上一页function beforePage() {if (pIndex 1) {pIndex parseInt(pIndex) - 1;location.href blog_list.html?pIndex pIndex;} else {alert(已经是首页了!!!)}}// 下一页function nextPage() {if (pIndex totalPage) {pIndex parseInt(pIndex) 1;location.href blog_list.html?pIndex pIndex;} else {alert(已经是末页了!!!)}}// 末页function lastPage() {location.href blog_list.html?pIndex totalPage;}// 使用这个 方法来初始话页面function initPage() {// 获取 当前页面的 查询字符串 比如 :?pIndex2let url location.search;if (url ! ) {// 将 问好 去掉 此时就剩下了 pIndex2 (假设页数是2)url url.substring(1);// let kvs url.split();let kvs url.split();// 获取到 跳转后的页数 ,pIndex kvs[1];}// 通过 getList 方法去获取到数据getList();}// 通过 initPage 方法来 初始化页面 .initPage();/script/body /htmlMath.ceil() - JavaScript | MDN (mozilla.org) 页面效果: 上面我们的代码其实还有一个没中不足的地方 我们的文章 应该是 后发布的在前面 而不是 以前发布的在前面 这里就来修改一下 也非常简单 就是给我们的SQL 加一个 排序 (按照时间排序即可) 到此我们的博客列表页的内容就完成了 , 下面就来完成我们的 博客详情页 4.4 博客详情页 这里我们主要实现查看 博客的功能 . 图一 图二 图三 图四 图五 图六 图七 前端代码 !DOCTYPE html html langen headmeta charsetUTF-8title博客详情页/titlelink relstylesheet href./css/common.csslink relstylesheet href./css/blog_detail.cssscript src./js/jquery.js/script!-- 引入 editor.md 的依赖--link relstylesheet href./editor.md/css/editormd.min.cssscript src./editor.md/lib/marked.min.js/scriptscript src./editor.md/lib/prettify.min.js/scriptscript src./editor.md/editormd.min.js/script/head body!-- 导航栏 -- div classnavimg src./imgs/阳台.pngspan classtitle我的博客系统/span!-- 这个标签仅仅用于占位 ,把下面几个a 标签挤到右边--div classspacer/diva href#主页/aa href#写博客/aa href#注销/a /div!-- 页面主体部分 -- div classcontainer!-- 左侧信息--div classcontainer-left!-- 使用 这个 .card 表示用户信息--div classcardimg src./imgs/girl.png alt图片显示失败!-- 用户名--h3牧/h3a href#Gitee 地址/adiv classcounterspan文章/spanspan分类/span/divdiv classcounterspan1/spanspan2/span/div/div/div!-- 右侧信息--div classcontainer-right!-- 博客标题 --h3 classtitle idtitle我的第一篇博客/h3!-- 博客发布时间--div classdate2023-03-02/div!-- 博客正文 --div idcontent!-- P--!-- 从今天开始我要认真敲代码--!-- 从今天开始我要认真敲代码--!-- 从今天开始我要认真敲代码--!-- 从今天开始我要认真敲代码--!-- /P--!-- P--!-- 从今天开始我要认真敲代码--!-- 从今天开始我要认真敲代码--!-- 从今天开始我要认真敲代码--!-- 从今天开始我要认真敲代码--!-- /P--!-- P--!-- 从今天开始我要认真敲代码--!-- 从今天开始我要认真敲代码--!-- 从今天开始我要认真敲代码--!-- 从今天开始我要认真敲代码--!-- /P--/div/div/divscriptfunction getBlogDetail() {jQuery.ajax({type: GET,// location.search 就是 ?blogIdxurl: /blog/getblog location.search,success: function (result) {if (result ! null result.data.status 0) {let data result.data.data;// 1. 构造博客标题let title document.querySelector(#title);title.innerHTML data.title;// 2. 构造发布时间let dateDiv document.querySelector(.date);dateDiv.innerHTML data.postTime;// 3. 构造正文部分// let content document.querySelector(.content);//// content.innerHTML data.content;// 使用 editormd.md 自带的方法 对内容进行渲染editormd.markdownToHTML(content, {markdown: data.content})let userid data.userid;jQuery.ajax({type: GET,url: /user/getuserbyid,data: {userid: userid,},success: function (result) {if (result ! null result.data.status 0) {let data result.data.data;// 通过子类选择器选中 img 元素let img document.querySelector(.cardimg);img.src product/ data.user.url;let title document.querySelector(.cardh3);title.innerHTML data.user.username;let spanArr document.querySelectorAll(.counterspan)spanArr[2].innerHTML data.blogNumber;spanArr[3].innerHTML data.type;} else {alert(设置错误!!!)}},error: function () {alert(出错了,请稍后再试!!)}})}}})}getBlogDetail();function getLoginUser() {jQuery.ajax({type: GET,url: /user/getuser,success: function (result) {if (result ! null result.data.status 0) {let img document.querySelector(.navimg);img.src product/ result.data.data.url;}}})}getLoginUser();/script/body /html 4.5 写博客功能 图一 图二 图三 图四 图五 最后完成我们的注销 功能 这个 小项目就完成了 . 4.6 注销功能 图一 图二 到此 这个 小项目就完成了 其实这个项目还有很多东西可以加 这些大家都可以 自由发挥 .
http://www.w-s-a.com/news/397105/

相关文章:

  • jsp网站建设模板下载十大免费excel网站
  • 网络公司网站图片网站建立好了自己怎么做优化
  • 云主机是不是可以搭建无数个网站百度快速seo优化
  • 房地产怎么做网站推广建立音乐网站
  • 川畅科技联系 网站设计网站开发的教学视频
  • 为什么学网站开发凡科登陆
  • 设计师常备设计网站大全中山精品网站建设信息
  • 杭州建设工程网seo服务是什么
  • 兼职做问卷调查的网站wordpress mysql设置
  • 怎么在百度上能搜到自己的网站山西seo谷歌关键词优化工具
  • 网站搭建免费模板飞鱼crm下载
  • 网站开发竞品分析app制作公司深圳
  • 网站建设ssc源码修复设计班级网站建设
  • 网站重定向凡科做网站不要钱
  • 佛山html5网站建设微信营销软件破解版
  • 网站单页做301南京百度推广
  • 私人做网站要多少钱展芒设计网页
  • 怎样网站制作设计如何在网上推广农产品
  • 做关键词排名卖网站聚名网
  • 吉林省住房城乡建设厅网站首页体育器材网站建设方案
  • 网站建设及维护专业手机金融界网站
  • 常州网站建设工作室建立网站有怎么用途
  • 如何盗取网站推广策划书模板
  • 游戏网站建设计划书网络开发需要学什么
  • 手机网站维护费网站开发包括网站过程
  • 懂做游戏钓鱼网站的网站建设技术的发展
  • 网站被百度收录百度一下你就知道 官网
  • 雅客网站建设做网站用什么做
  • 做宣传海报网站专业网站设计速寻亿企邦
  • 秦皇岛市住房和城乡建设局网站有关网站开发的参考文献