• 基于NodeJs+Express+MySQL 实现的个人博客完整项目


    目录

    一、创建项目并初始化

    项目结构

    二、安装项目所需要的包

    三、创建所需要的数据库表

    表 user 用于存放账户密码

    表 notepad 用于存放文章数据

    表 leaving 用于存放留言板的数据

    三、编写app.js文件

    1、导入所有需要的包

    2、创建web服务器

    3、创建db文件夹,在文件夹里面创建mysql.js 注册连接数据库的路由

    4、配置中间件、跨域 和sssion认证

    6、开始接口的配置

    四、创建个人博客的页面

    五、展示个人博客页面

    项目地址:https://gitee.com/danke-hang/Node

    实现的功能: 多用户登录,注册,session认证,通过数据库展示文章列表、文章详情,动态生成文章页面,文章分页查询,留言板功能

    一、创建项目并初始化

    项目结构

    二、安装项目所需要的包

    npm install msyql

    npm install express

    npm install ejs

    三、创建所需要的数据库表

    表 user 用于存放账户密码

    1. CREATE TABLE user (
    2. username varchar(100),
    3. password varchar(100)
    4. )

    表 notepad 用于存放文章数据

    1. CREATE TABLE notepad (
    2. id int(11) NOT NULL AUTO_INCREMENT,
    3. username varchar(100),
    4. title varchar(100),
    5. content varchar(9999),
    6. time varchar(99),
    7. PRIMARY KEY (`id`)
    8. )

    表 leaving 用于存放留言板的数据

    1. CREATE TABLE leaving (
    2. username varchar(100),
    3. content varchar(9999),
    4. time varchar(100)
    5. )

    三、编写app.js文件

    1、导入所有需要的包

    1. // 导入express
    2. const express = require('express')
    3. var bodyParser = require('body-parser');
    4. // 导入数据库操作模块
    5. const db = require('./db/mysql')
    6. // 导入 session 中间件
    7. var session = require('express-session')
    8. const ejs=require("ejs");
    9. const fs=require("fs");

    2、创建web服务器

    1. // 创建web服务器
    2. const app = express()
    3. // 调用app.listen(端口号, 启动成功后的回调函数) 启动服务器
    4. app.listen(80, () => {
    5. console.log('127.0.0.1');
    6. })

    3、创建db文件夹,在文件夹里面创建mysql.js 注册连接数据库的路由

    mysql.js

    1. // 1. 导入 mysql 模块
    2. const mysql = require('mysql')
    3. // 2. 建立与 MySQL 数据库的连接关系
    4. const db = mysql.createPool({
    5. host: 'localhost', // 数据库的 IP 地址
    6. user: 'root', // 登录数据库的账号
    7. password: 'root', // 登录数据库的密码
    8. database: 'movies', // 指定要操作哪个数据库
    9. })
    10. module.exports = db

    4、配置中间件、跨域 和sssion认证

    1. // 设置默认首页
    2. // app.use(myexpress.static(__dirname+"/public",{index:"首页地址"}));
    3. app.use(function(req, res) {
    4. res.send('404 NOT Found')
    5. })
    6. app.use(express.static(__dirname+"/pages",{index:"login.html"}));
    7. // 跨域
    8. app.use(cors())
    9. app.use(session({
    10. secret: 'keyboard cat', // secret 属性的值可以为任意字符串
    11. resave: false, // 固定写法
    12. saveUninitialized: true // 固定写法
    13. }))
    14. // 中间件定义post传递的格式
    15. app.use(express.static('./pages'))
    16. // 静态资源托管
    17. app.use('/public', express.static('./public'))
    18. app.use(express.json())
    19. app.use(bodyParser.urlencoded({extended:true}));//Context-Type 为application/x-www-form-urlencoded 时 返回的对象是一个键值对,当extended为false的时候,键值对中的值就为'String'或'Array'形式,为true的时候,则可为任何数据类型。
    20. app.use(bodyParser.json());//用于解析json 会自动选择最为适宜的解析方式于解析json 会自动选择最为适宜的解析方式

    6、开始接口的配置

    登录接口

    1. app.post('/api/getUsername', function(req, res) {
    2. const sqlStr = 'SELECT username,password FROM user;'
    3. db.query(sqlStr, (err, results) => {
    4. // 查询数据失败
    5. if (err) return console.log(err.message)
    6. console.log(results);
    7. // 查询数据成功
    8. // 注意:如果执行的是 select 查询语句,则执行的结果是数组
    9. let userData = results.map(item => item.username)
    10. let pwdData = results.map(item => item.password)
    11. if (userData.indexOf(req.body.username) == -1) {
    12. res.send({
    13. status: 400,
    14. message: '该用户不存在',
    15. })
    16. } else {
    17. // 用户存在,判断密码
    18. if (req.body.password == pwdData[userData.indexOf(req.body.username)]) {
    19. // 将用户的信息,存储到Session中
    20. req.session.user = req.body
    21. // 将用户的登陆状态,存储到Session中
    22. req.session.islogin = true
    23. res.send({
    24. status: 200,
    25. message: '登录成功',
    26. })
    27. } else {
    28. res.send({
    29. status: 401,
    30. message: '登录失败,密码不正确',
    31. })
    32. }
    33. }
    34. })
    35. })

    注册接口

    1. app.post('/api/register', function(req, res) {
    2. // 判断数据库里是否已经存在该用户名,如果没有则注册,如果有则提示重新注册
    3. const sqlStr = 'SELECT username FROM user;'
    4. db.query(sqlStr, (err, results) => {
    5. // 查询数据失败
    6. if (err) {
    7. return console.log(err.message)
    8. } else {
    9. let userData = results.map(item => item.username)
    10. // 判断注册的账号是否与数据库里的账号相同 -1 代表数据库里不存在此数据
    11. if (userData.indexOf(req.body.username) == -1) {
    12. const sqlStr = `INSERT into user (username, password) VALUES ( '${req.body.username}', '${req.body.password}' );`
    13. db.query(sqlStr, (err, results) => {
    14. // 查询数据失败
    15. if (err) {
    16. return console.log(err.message)
    17. } else {
    18. res.send({
    19. status: 200,
    20. message: '注册成功'
    21. })
    22. }
    23. })
    24. } else {
    25. res.send({
    26. status: 400,
    27. message: '账号已存在,请重新注册'
    28. })
    29. }
    30. }
    31. })
    32. })

    获取用户姓名的接口

    1. app.get('/api/username', (req, res) => {
    2. // 判断用户是否登录
    3. if ( !req.session.islogin) {
    4. return res.send({
    5. status: 404,
    6. msg: 'fail'
    7. })
    8. }
    9. res.send({
    10. status: 200,
    11. msg: 'success',
    12. username: req.session.user.username
    13. })
    14. })

    退出登录的接口

    1. app.post('/api/logout', (req, res) => {
    2. req.session.destroy()
    3. res.send({
    4. status: 200,
    5. msg: '退出登陆成功',
    6. })
    7. })

    获取文章列表

    1. app.get('/api/getArticle', (req, res) => {
    2. const sqlStr = 'SELECT * FROM Notepad;'
    3. db.query(sqlStr, (err, results) => {
    4. // 查询数据失败
    5. if (err) {
    6. return console.log(err.message)
    7. } else {
    8. res.send({
    9. status: 200,
    10. message: '获取文章成功',
    11. data: results,
    12. username: req.session.user.username
    13. })
    14. }
    15. })
    16. })

    新增文章接口

    1. app.post('/api/addArticle', (req, res) => {
    2. let time = new Date()
    3. const sqlStr = `INSERT into Notepad VALUES (null, '${req.session.user.username}', '${req.body.title}', '${req.body.content}', '${time.toLocaleString()}');`
    4. db.query(sqlStr, (err, results) => {
    5. // 查询数据失败
    6. if (err) {
    7. return console.log(err.message)
    8. } else {
    9. res.send({
    10. status: 201,
    11. message: '添加文章成功',
    12. data: {}
    13. })
    14. }
    15. })
    16. })

    查找文章接口

    1. app.post('/api/search', (req, res) => {
    2. let time = new Date()
    3. const sqlStr = `SELECT * FROM notepad where id=${req.body.id};`
    4. db.query(sqlStr, (err, results) => {
    5. // 查询数据失败
    6. if (err) {
    7. return console.log(err.message)
    8. } else {
    9. res.send({
    10. status: 200,
    11. message: "查找成功",
    12. data: results
    13. })
    14. }
    15. })
    16. })

    动态获取接口用于渲染文章

    1. app.get('/:_id', (req, res) => {
    2. var num = req.params._id
    3. num = num.replace('_id', '')
    4. num = parseInt(num)
    5. // 根据id查找相应的数据
    6. const sqlStr = `SELECT * FROM Notepad where id=${num};`
    7. db.query(sqlStr, (err, results) => {
    8. // 查询数据失败
    9. if (err) {
    10. return console.log(err.message)
    11. } else {
    12. res.render("index.ejs",{
    13. username: results[0].username,
    14. title:results[0].title,
    15. content: results[0].content,
    16. time: results[0].time,
    17. })
    18. }})
    19. })

    获取留言接口 

    1. // 获取评论
    2. app.get('/api/getlist',(req,res)=>{
    3. const sqlStr = 'select * from leaving'
    4. db.query(sqlStr, (err, results) => {
    5. // 失败
    6. if (err) {
    7. return console.log(err.message)
    8. }
    9. res.send({
    10. code: 200,
    11. msg: '获取评论列表成功',
    12. data: results,
    13. username: req.session.user.username
    14. })
    15. })
    16. })

    新增留言接口

    1. // 增加评论
    2. app.post('/api/addlist', (req, res) => {
    3. let time = new Date()
    4. // 获取到客户端通过查询字符串,发送到服务器的数据
    5. // const sqlStr3 = `INSERT INTO leaving VALUES ('${body.text}');`
    6. const sqlStr = `INSERT INTO leaving VALUES ('${req.session.user.username}','${req.body.content}','${time.toLocaleString()}');`
    7. db.query(sqlStr, (err, results) => {
    8. // 失败
    9. if (err) {
    10. return console.log(err.message)
    11. }
    12. res.send({
    13. status: 200,
    14. msg: '添加数据成功',
    15. data: results,
    16. username: req.session.user.username
    17. })
    18. })
    19. })

    分页查询接口 

    1. app.post('/api/limit', (req, res) => {
    2. const sqlStr = `SELECT * FROM notepad LIMIT 10 OFFSET ${req.body.num};`
    3. db.query(sqlStr, (err, results) => {
    4. // 失败
    5. if (err) {
    6. return console.log(err.message)
    7. }
    8. res.send({
    9. status: 200,
    10. msg: '分页查询成功',
    11. data: results,
    12. })
    13. })
    14. })

    四、创建个人博客的页面

    登录页面   login.html

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>用户登录title>
    8. <script src="./jQuery.mini.js">script>
    9. <script src="./axios.js">script>
    10. <link rel="shortcut icon" href="favicon.ico">
    11. <style>
    12. * {
    13. margin: 0;
    14. padding: 0;
    15. }
    16. html {
    17. height: 100%;
    18. }
    19. body {
    20. height: 100%;
    21. background-image: url(../public/wallhaven-6k3lk6.jpg);
    22. }
    23. .container {
    24. height: 100%;
    25. background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);
    26. }
    27. .login-wrapper {
    28. background-color: #fff;
    29. width: 358px;
    30. height: 588px;
    31. border-radius: 15px;
    32. padding: 0 50px;
    33. position: relative;
    34. left: 50%;
    35. top: 50%;
    36. transform: translate(-50%, -50%);
    37. }
    38. .header {
    39. font-size: 38px;
    40. font-weight: bold;
    41. text-align: center;
    42. line-height: 200px;
    43. }
    44. .input-item {
    45. display: block;
    46. width: 100%;
    47. margin-bottom: 20px;
    48. border: 0;
    49. padding: 10px;
    50. border-bottom: 1px solid rgb(128, 125, 125);
    51. font-size: 15px;
    52. outline: none;
    53. }
    54. .input-item:placeholder {
    55. text-transform: uppercase;
    56. }
    57. .login,.register {
    58. text-align: center;
    59. padding: 10px;
    60. width: 100%;
    61. margin-top: 40px;
    62. background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
    63. color: #fff;
    64. }
    65. .msg {
    66. text-align: center;
    67. line-height: 88px;
    68. }
    69. a {
    70. text-decoration-line: none;
    71. color: #abc1ee;
    72. }
    73. .box {
    74. width: 5.333333333333333rem;
    75. height: 4.8rem;
    76. font-size: 1.173333333333333rem;
    77. }
    78. @media (width:375px) {
    79. html {
    80. font-size: 37.5px;
    81. }
    82. }
    83. /* 按钮当鼠标悬浮时的状态: */
    84. .btn:hover{
    85. transform: translateY(-3px);
    86. box-shadow: 0 10px 20px rgba(0,0,0,0.2);
    87. }
    88. .btn {
    89. transition: all .2s ;
    90. border-radius: 10px;
    91. }
    92. .tankuang{
    93. display: none;
    94. position: relative;
    95. background: #a6c1ee;
    96. z-index: 99;
    97. width: 250px;
    98. height: 100px;
    99. text-align: center;
    100. line-height: 100px;
    101. border-radius: 5px;
    102. top: 40%;
    103. left: 50%;
    104. transform: translate(-50%, -50%);
    105. }
    106. style>
    107. head>
    108. <body>
    109. <div class="tankuang">
    110. <div id="header">
    111. <span style="color:#ffffff; font-size:20px;margin: auto;line-height: 50px;" id="layer_msg">span>
    112. div>
    113. div>
    114. <div class="container">
    115. <div class="login-wrapper">
    116. <div class="header">HELLO HANGdiv>
    117. <div class="form-wrapper">
    118. <form action="" id="form_login">
    119. <input type="text" name="username" placeholder="账号" class="input-item" id="user">
    120. <input type="password" name="password" placeholder="密码" class="input-item" id="pwd">
    121. <div class="login btn">登录div>
    122. <div class="register btn">去注册div>
    123. form>
    124. div>
    125. <div class="msg">
    126. 有问题?
    127. <a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长a>
    128. div>
    129. div>
    130. div>
    131. <script>
    132. $(function() {
    133. $('.login').click(function(e){
    134. e.preventDefault()
    135. var data = $('#form_login').serialize()
    136. $.post(
    137. 'http://127.0.0.1/api/getUsername',
    138. data,
    139. function(res) {
    140. if (res.status == 400){
    141. document.querySelector('.tankuang').style.display = 'block',
    142. document.querySelector('.container').style.marginTop = '-100px'
    143. $('#layer_msg').text('账号不存在,请先注册')
    144. setTimeout(function(){
    145. document.querySelector('.tankuang').style.display = 'none',
    146. document.querySelector('.container').style.marginTop = '0px'
    147. },1000)
    148. } else if (res.status == 401) {
    149. document.querySelector('.tankuang').style.display = 'block',
    150. document.querySelector('.container').style.marginTop = '-100px'
    151. $('#layer_msg').text('密码错误,请重新登录')
    152. setTimeout(function(){
    153. document.querySelector('.tankuang').style.display = 'none',
    154. document.querySelector('.container').style.marginTop = '0px'
    155. },1000)
    156. } else {
    157. location.href = './index.html'
    158. }
    159. }
    160. )
    161. })
    162. $(document).keyup(function(e){
    163. e.preventDefault()
    164. if (e.keyCode == '13') {
    165. var data = $('#form_login').serialize()
    166. $.post(
    167. 'http://127.0.0.1/api/getUsername',
    168. data,
    169. function(res) {
    170. if (res.status == 400){
    171. document.querySelector('.tankuang').style.display = 'block',
    172. document.querySelector('.container').style.marginTop = '-100px'
    173. $('#layer_msg').text('账号不存在,请先注册')
    174. setTimeout(function(){
    175. document.querySelector('.tankuang').style.display = 'none',
    176. document.querySelector('.container').style.marginTop = '0px'
    177. },1000)
    178. } else if (res.status == 401) {
    179. document.querySelector('.tankuang').style.display = 'block',
    180. document.querySelector('.container').style.marginTop = '-100px'
    181. $('#layer_msg').text('密码错误,请重新登录')
    182. setTimeout(function(){
    183. document.querySelector('.tankuang').style.display = 'none',
    184. document.querySelector('.container').style.marginTop = '0px'
    185. },1000)
    186. } else {
    187. location.href = './index.html'
    188. }
    189. }
    190. )
    191. }
    192. })
    193. $('.register').click(function(e){
    194. e.preventDefault()
    195. location.href = './register.html'
    196. })
    197. })
    198. script>
    199. body>
    200. html>

    注册页面

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>用户注册title>
    8. <script src="./jQuery.mini.js">script>
    9. <script src="./axios.js">script>
    10. <link rel="shortcut icon" href="favicon.ico">
    11. <style>
    12. * {
    13. margin: 0;
    14. padding: 0;
    15. }
    16. html {
    17. height: 100%;
    18. }
    19. body {
    20. height: 100%;
    21. background-image: url(../public/wallhaven-6k3lk6.jpg);
    22. }
    23. .container {
    24. height: 100%;
    25. background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);
    26. }
    27. .login-wrapper {
    28. background-color: #fff;
    29. width: 358px;
    30. height: 588px;
    31. border-radius: 15px;
    32. padding: 0 50px;
    33. position: relative;
    34. left: 50%;
    35. top: 50%;
    36. transform: translate(-50%, -50%);
    37. }
    38. .header {
    39. font-size: 38px;
    40. font-weight: bold;
    41. text-align: center;
    42. line-height: 200px;
    43. }
    44. .input-item {
    45. display: block;
    46. width: 100%;
    47. margin-bottom: 20px;
    48. border: 0;
    49. padding: 10px;
    50. border-bottom: 1px solid rgb(128, 125, 125);
    51. font-size: 15px;
    52. outline: none;
    53. }
    54. .input-item:placeholder {
    55. text-transform: uppercase;
    56. }
    57. .login,.register {
    58. text-align: center;
    59. padding: 10px;
    60. width: 100%;
    61. margin-top: 40px;
    62. background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
    63. color: #fff;
    64. }
    65. .msg {
    66. text-align: center;
    67. line-height: 88px;
    68. }
    69. a {
    70. text-decoration-line: none;
    71. color: #abc1ee;
    72. }
    73. .box {
    74. width: 5.333333333333333rem;
    75. height: 4.8rem;
    76. font-size: 1.173333333333333rem;
    77. }
    78. @media (width:375px) {
    79. html {
    80. font-size: 37.5px;
    81. }
    82. }
    83. /* 按钮当鼠标悬浮时的状态: */
    84. .btn:hover{
    85. transform: translateY(-3px);
    86. box-shadow: 0 10px 20px rgba(0,0,0,0.2);
    87. }
    88. .btn {
    89. transition: all .2s ;
    90. border-radius: 10px;
    91. }
    92. .tankuang{
    93. display: none;
    94. position: relative;
    95. background: #a6c1ee;
    96. z-index: 99;
    97. width: 250px;
    98. height: 100px;
    99. text-align: center;
    100. line-height: 100px;
    101. border-radius: 5px;
    102. top: 40%;
    103. left: 50%;
    104. transform: translate(-50%, -50%);
    105. }
    106. style>
    107. head>
    108. <body>
    109. <div class="tankuang">
    110. <div id="header">
    111. <span style="color:#ffffff; font-size:20px;margin: auto;line-height: 50px;" id="layer_msg">span>
    112. div>
    113. div>
    114. <div class="container">
    115. <div class="login-wrapper">
    116. <div class="header">REGISTERdiv>
    117. <div class="form-wrapper">
    118. <form action="" id="form_login">
    119. <input type="text" name="username" placeholder="账号" class="input-item" id="user">
    120. <input type="password" name="password" placeholder="密码" class="input-item" id="pwd">
    121. <div class="register btn">注册div>
    122. form>
    123. div>
    124. <div class="msg">
    125. 有问题?
    126. <a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长a>
    127. div>
    128. div>
    129. div>
    130. <script>
    131. $(function() {
    132. $('.register').click(function(e){
    133. e.preventDefault()
    134. var data = $('#form_login').serialize()
    135. $.post(
    136. 'http://192.168.30.71/api/register',
    137. data,
    138. function(res) {
    139. console.log(res);
    140. if(res.status == 200) {
    141. document.querySelector('.tankuang').style.display = 'block',
    142. document.querySelector('.container').style.marginTop = '-100px'
    143. $('#layer_msg').text('注册成功')
    144. setTimeout(function(){
    145. location.href = './login.html'
    146. },1000)
    147. } else {
    148. document.querySelector('.tankuang').style.display = 'block',
    149. document.querySelector('.container').style.marginTop = '-100px'
    150. $('#layer_msg').text('账号已存在,请重新注册')
    151. setTimeout(function(){
    152. document.querySelector('.tankuang').style.display = 'none',
    153. document.querySelector('.container').style.marginTop = '0px'
    154. },1000)
    155. }
    156. }
    157. )
    158. })
    159. })
    160. script>
    161. body>
    162. html>

    博客主页 index.html  可进行分页查询

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <title>Documenttitle>
    7. <script src="./jQuery.mini.js">script>
    8. <link rel="stylesheet" href="./bootstrap.css">
    9. <script src="./axios.js">script>
    10. <style>
    11. body {
    12. background-repeat: no-repeat;
    13. background-size: cover;
    14. }
    15. .navbar {
    16. z-index: 99;
    17. }
    18. .name {
    19. display: flex;
    20. justify-content: space-between;
    21. float: right;
    22. width: 26rem;
    23. height: 100%;
    24. font-size: .875rem;
    25. color: #696767;
    26. /* background-color: aqua; */
    27. }
    28. .collapse {
    29. width: 250px;
    30. display: flex;
    31. justify-content: space-around;
    32. }
    33. .container {
    34. width: 100%;
    35. height: 100%;
    36. }
    37. .listbig {
    38. font-size: 18px;
    39. }
    40. .list_a {
    41. font-size: 16px;
    42. }
    43. .limit {
    44. text-align: center;
    45. }
    46. .list-group {
    47. height: 550px;
    48. }
    49. style>
    50. head>
    51. <body>
    52. <nav class="navbar navbar-default">
    53. <div class="container-fluid">
    54. <div class="navbar-header">
    55. <a class="navbar-brand" href="#">文章列表a>
    56. div>
    57. <ul class="nav navbar-nav">
    58. <li><a href="./addarticle.html">添加文章 a>li>
    59. <li><a href="./leaving.html">留言板 a>li>
    60. ul>
    61. <div class="collapse navbar-right" id="bs-example-navbar-collapse-1">
    62. <ul class="nav navbar-nav ">
    63. <li><a href="#" class="user">a>li>
    64. ul>
    65. <ul class="nav navbar-nav ">
    66. <li><a href="#" id="btnLogout">退出登录a>li>
    67. ul>
    68. div>
    69. div>
    70. nav>
    71. <div class="list-group">
    72. <a href="#" class="list-group-item active listbig">
    73. 文章列表
    74. a>
    75. div>
    76. <nav aria-label="Page navigation" class="limit">
    77. <ul class="pagination">
    78. <li><a href="#" id="1">1a>li>
    79. <li><a href="#" id="2">2a>li>
    80. <li><a href="#" id="3">3a>li>
    81. <li><a href="#" id="4">4a>li>
    82. <li><a href="#" id="5">5a>li>
    83. ul>
    84. nav>
    85. <script>
    86. $(function () {
    87. // 点击文章列表切换页面
    88. $('.list-group').on('click', 'a', function(e){
    89. // 获取点击文字的id值
    90. var list_id = e.target.id
    91. // 获取文章列表进行文章筛选
    92. axios({
    93. method: 'GET',
    94. url: 'http://127.0.0.1/api/getArticle',
    95. }).then(function(res) {
    96. // console.log(list_id);
    97. var data = {id: list_id}
    98. // 筛选文章
    99. axios({
    100. method: 'POST',
    101. data,
    102. url: 'http://127.0.0.1/api/search',
    103. }).then(function(res) {
    104. if (res.data.status == 200) {
    105. console.log(res.data);
    106. console.log(res.data.data.content);
    107. } else {
    108. alert('文章不存在!')
    109. }
    110. })
    111. })
    112. })
    113. // 获取用户名判断是否登录
    114. $.get(
    115. 'http://127.0.0.1/api/username',
    116. function(res) {
    117. // console.log(res);
    118. if (res.status == 200) {
    119. let username = res.username
    120. $('.user').text(username)
    121. let data = {num: 0}
    122. // 获取文章列表
    123. axios({
    124. method: 'POST',
    125. data,
    126. url: 'http://127.0.0.1/api/limit',
    127. }).then(function(res) {
    128. // 将获取到的文章渲染到页面 作为初始页面
    129. res.data.data.map(item => {
    130. $('.list-group').append(a)
    131. })
    132. })
    133. } else {
    134. alert('请先完成登录')
    135. location.href = './login.html'
    136. }
    137. }
    138. )
    139. // 退出登录
    140. $('#btnLogout').click(function() {
    141. $.post(
    142. 'http://127.0.0.1/api/register',
    143. function(res) {
    144. if (res.status == 200) {
    145. // 如果 status 为 200,则表示退出成功,重新跳转到登录页面
    146. location.href = './login.html'
    147. }
    148. }
    149. )
    150. })
    151. // 分页查询
    152. $('.limit').on('click', 'li', function(e){
    153. let data = {num: parseInt((e.target.id-1) * 10)}
    154. axios({
    155. method: 'POST',
    156. data,
    157. url: 'http://127.0.0.1/api/limit',
    158. }).then(function(res) {
    159. if (res.data.status == 200) {
    160. $('.list-group').empty('')
    161. $('.list-group').append('文章列表')
    162. res.data.data.map(item => {
    163. $('.list-group').append(a)
    164. })
    165. } else {
    166. alert('查询失败!')
    167. }
    168. })
    169. })
    170. })
    171. script>
    172. body>
    173. html>

    添加文章的页面 

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <title>Documenttitle>
    7. <script src="./jQuery.mini.js">script>
    8. <link rel="stylesheet" href="./bootstrap.css">
    9. <script src="./axios.js">script>
    10. <style>
    11. * {
    12. margin: 0;
    13. padding: 0;
    14. }
    15. html {
    16. height: 1200px;
    17. }
    18. body {
    19. height: 1200px;
    20. }
    21. .container {
    22. width: 100%;
    23. height: 100%;
    24. /* background-image: linear-gradient(to right, #26453d, #0b1013); */
    25. /* background-image: linear-gradient(to right, #a7a8bd, #2e317c); */
    26. background-image: linear-gradient(to bottom, #a7a8bd, #2e317c);
    27. }
    28. .login-wrapper {
    29. background-color: #fff;
    30. width: 700px;
    31. height: 900px;
    32. border-radius: 15px;
    33. padding: 0 50px;
    34. position: relative;
    35. text-align: center;
    36. margin: 0 auto;
    37. /* left: 50%;
    38. top: 50%;
    39. transform: translate(-50%, -50%); */
    40. }
    41. .header {
    42. font-size: 38px;
    43. font-weight: bold;
    44. text-align: center;
    45. line-height: 80px;
    46. }
    47. .input-item {
    48. display: block;
    49. width: 100%;
    50. margin-bottom: 20px;
    51. border: 0;
    52. padding: 10px;
    53. border-bottom: 1px solid rgb(128, 125, 125);
    54. font-size: 15px;
    55. outline: none;
    56. }
    57. .input-item:placeholder {
    58. text-transform: uppercase;
    59. }
    60. /* .navbar {
    61. margin-top: -100px;
    62. } */
    63. .btn {
    64. text-align: center;
    65. padding: 10px;
    66. width: 100%;
    67. margin-top: 40px;
    68. background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
    69. }
    70. .msg {
    71. text-align: center;
    72. line-height: 200px;
    73. }
    74. a {
    75. text-decoration-line: none;
    76. color: #abc1ee;
    77. }
    78. /* 按钮当鼠标悬浮时的状态: */
    79. .btn:hover{
    80. transform: translateY(-3px);
    81. box-shadow: 0 10px 20px rgba(0,0,0,0.2);
    82. }
    83. .btn {
    84. transition: all .2s ;
    85. border-radius: 10px;
    86. }
    87. .tankuang{
    88. display: none;
    89. position: relative;
    90. background: #305a56;
    91. z-index: 99;
    92. width: 200px;
    93. height: 100px;
    94. text-align: center;
    95. line-height: 100px;
    96. border-radius: 5px;
    97. top: 30%;
    98. left: 50%;
    99. transform: translate(-50%, -50%);
    100. }
    101. style>
    102. head>
    103. <body>
    104. <div class="tankuang">
    105. <div id="header">
    106. <span style="color:#ffffff; font-size:20px;margin: auto;line-height: 50px;" id="layer_msg">提交成功...span>
    107. div>
    108. div>
    109. <nav class="navbar navbar-default">
    110. <div class="container-fluid">
    111. <div class="navbar-header">
    112. <a class="navbar-brand" href="./index.html">返回主页a>
    113. div>
    114. <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
    115. <ul class="nav navbar-nav navbar-right">
    116. <li><a href="#" id="btnLogout">退出登录a>li>
    117. ul>
    118. div>
    119. div>
    120. nav>
    121. <div class="container">
    122. <div class="login-wrapper">
    123. <div class="header">写文章div>
    124. <form id="form_add">
    125. <div class="form-wrapper">
    126. <div class="input-group">
    127. <span class="input-group-addon" id="basic-addon3" >文章标题span>
    128. <input type="text" class="form-control" id="basic-url" name="title" aria-describedby="basic-addon3">
    129. div>
    130. <h3>文章内容h3>
    131. <textarea class="form-control" rows="18" name="content" style="font-size: 16px;">textarea>
    132. <div class="btn">发布文章div>
    133. div>
    134. form>
    135. <div class="msg">
    136. 有问题?
    137. <a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长a>
    138. div>
    139. div>
    140. div>
    141. <script>
    142. $(function(){
    143. // 发布文章
    144. $('.btn').click(function(e){
    145. e.preventDefault()
    146. var data = $('#form_add').serialize()
    147. axios({
    148. method: 'POST',
    149. url: 'http://127.0.0.1/api/addArticle',
    150. data
    151. }).then(function(res){
    152. if (res.data.status == 201) {
    153. document.querySelector('.tankuang').style.display = 'block',
    154. document.querySelector('.navbar').style.marginTop = '-100px'
    155. setTimeout(function(){
    156. location.href = './index.html'
    157. },800)
    158. } else {
    159. alert('文章发布失败')
    160. }
    161. })
    162. })
    163. // 获取用户名判断是否登录
    164. $.get(
    165. 'http://127.0.0.1/api/username',
    166. function(res) {
    167. console.log(res);
    168. if (res.status == 200) {
    169. // alert('登陆成功!欢迎'+res.username)
    170. } else {
    171. alert('请先完成登录')
    172. location.href = './login.html'
    173. }
    174. }
    175. )
    176. // 退出登录
    177. $('#btnLogout').click(function() {
    178. $.post(
    179. 'http://127.0.0.1/api/register',
    180. function(res) {
    181. if (res.status == 200) {
    182. // 如果 status 为 200,则表示退出成功,重新跳转到登录页面
    183. location.href = './login.html'
    184. }
    185. }
    186. )
    187. })
    188. })
    189. script>
    190. body>
    191. html>

     渲染文章的页面,使用的ejs     index.ejs

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <script src="./jQuery.mini.js">script>
    6. <script src="./axios.js">script>
    7. <title>Titletitle>
    8. <style>
    9. * {
    10. margin: 0;
    11. padding: 0;
    12. }
    13. html {
    14. height: 1400px;
    15. }
    16. body {
    17. height: 1400px;
    18. }
    19. .container {
    20. height: 100%;
    21. /* background-image: linear-gradient(to right, #999999, #330867); */
    22. /* background-image: linear-gradient(to right, #b5caa0, #1b813e); */
    23. background-image: linear-gradient(to bottom, #91b493, #096148);
    24. }
    25. .login-wrapper {
    26. background-color: #fff;
    27. width: 800px;
    28. /* height: 1200px; */
    29. border-radius: 15px;
    30. padding: 0 50px;
    31. position: relative;
    32. text-align: center;
    33. margin: 0 auto;
    34. /* left: 50%;
    35. top: 50%;
    36. transform: translate(-50%,-50%); */
    37. /* table-layout:fixed; */
    38. /* word-break:break-all; */
    39. /* overflow:hidden; */
    40. /* word-break: break-all;word-wrap: break-word; */
    41. }
    42. .header {
    43. font-size: 38px;
    44. font-weight: bold;
    45. text-align: center;
    46. line-height: 100px;
    47. }
    48. .other {
    49. font-size: 14px;
    50. line-height: 30px;
    51. color: #696767;;
    52. }
    53. /* div{ word-wrap: break-word; word-break: normal;} */
    54. .content {
    55. overflow: hidden;
    56. text-indent: 2rem;
    57. text-align: left;
    58. margin: 30px auto;
    59. width: 700px;
    60. /* height: 900px; */
    61. line-height: 1rem;
    62. /* background-color: #abc1ee; */
    63. word-break: break-all;
    64. word-wrap: break-word;
    65. table-layout:fixed;
    66. }
    67. .msg {
    68. text-align: center;
    69. line-height: 200px;
    70. }
    71. a {
    72. text-decoration-line: none;
    73. color: #abc1ee;
    74. }
    75. style>
    76. head>
    77. <body>
    78. <div class="container">
    79. <div class="login-wrapper">
    80. <div class="header"><%- title %>div>
    81. <div class="other">
    82. <div class="name">用户: <%- username %>div>
    83. <div class="time"><%- time %>div>
    84. div>
    85. <div class="content">
    86. |<pre><%- content %>pre>
    87. div>
    88. <div class="msg">
    89. 有问题?
    90. <a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长a>
    91. div>
    92. div>
    93. div>
    94. <script>
    95. // 获取用户名判断是否登录
    96. $.get(
    97. 'http://127.0.0.1/api/username',
    98. function(res) {
    99. console.log(res);
    100. if (res.status == 200) {
    101. // alert('登陆成功!欢迎'+res.username)
    102. } else {
    103. alert('请先完成登录')
    104. location.href = './login.html'
    105. }
    106. }
    107. )
    108. script>
    109. body>
    110. html>

    留言板,用于展示留言,添加留言

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <title>Documenttitle>
    7. <script src="./jQuery.mini.js">script>
    8. <link rel="stylesheet" href="./bootstrap.css">
    9. <script src="./axios.js">script>
    10. <style>
    11. * {
    12. margin: 0;
    13. padding: 0;
    14. }
    15. .container {
    16. width: 100%;
    17. height: 100%;
    18. background-image: linear-gradient(to bottom, #f9f4dc, #ecb88a);
    19. }
    20. .login-wrapper {
    21. background-color: #fff;
    22. width: 700px;
    23. /* height: 900px; */
    24. border-radius: 15px;
    25. padding: 0 50px;
    26. position: relative;
    27. text-align: center;
    28. margin: 0 auto;
    29. /* left: 50%;
    30. top: 50%;
    31. transform: translate(-50%, -50%); */
    32. }
    33. .header {
    34. font-size: 38px;
    35. font-weight: bold;
    36. text-align: center;
    37. line-height: 80px;
    38. }
    39. .input-item {
    40. display: block;
    41. width: 100%;
    42. margin-bottom: 20px;
    43. border: 0;
    44. padding: 10px;
    45. border-bottom: 1px solid rgb(128, 125, 125);
    46. font-size: 15px;
    47. outline: none;
    48. }
    49. .input-item:placeholder {
    50. text-transform: uppercase;
    51. }
    52. .btn {
    53. text-align: center;
    54. padding: 10px;
    55. width: 100%;
    56. margin-top: 40px;
    57. background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
    58. }
    59. .msg {
    60. text-align: center;
    61. line-height: 200px;
    62. }
    63. a {
    64. text-decoration-line: none;
    65. color: #abc1ee;
    66. }
    67. /* 按钮当鼠标悬浮时的状态: */
    68. .btn:hover{
    69. transform: translateY(-3px);
    70. box-shadow: 0 10px 20px rgba(0,0,0,0.2);
    71. }
    72. .btn {
    73. transition: all .2s ;
    74. border-radius: 10px;
    75. }
    76. style>
    77. head>
    78. <body>
    79. <div class="tankuang">
    80. <div id="header">
    81. <span style="color:#ffffff; font-size:20px;margin: auto;line-height: 50px;" id="layer_msg">span>
    82. div>
    83. div>
    84. <nav class="navbar navbar-default">
    85. <div class="container-fluid">
    86. <div class="navbar-header">
    87. <a class="navbar-brand" href="./index.html">返回主页a>
    88. div>
    89. <div class="collapse navbar-right" id="bs-example-navbar-collapse-1">
    90. <ul class="nav navbar-nav ">
    91. <li><a href="#" class="user">123123a>li>
    92. ul>
    93. <ul class="nav navbar-nav">
    94. <li><a href="#" id="btnLogout">退出登录a>li>
    95. ul>
    96. div>
    97. div>
    98. nav>
    99. <div class="container">
    100. <div class="login-wrapper">
    101. <div class="header">留言板div>
    102. <form id="form_add">
    103. <div class="form-wrapper">
    104. <ul class="list-group">
    105. ul>
    106. <textarea class="form-control" rows="10" name="content" style="font-size: 16px;">textarea>
    107. <div class="btn">发布留言div>
    108. div>
    109. form>
    110. <div class="msg">
    111. 有问题?
    112. <a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长a>
    113. div>
    114. div>
    115. div>
    116. <script>
    117. $(function(){
    118. // 发布留言
    119. $('.btn').click(function(e){
    120. e.preventDefault()
    121. var data = $('#form_add').serialize()
    122. axios({
    123. method: 'POST',
    124. url: 'http://127.0.0.1/api/addlist',
    125. data
    126. }).then(function(res){
    127. if (res.data.status == 200) {
    128. // 刷新页面
    129. location.reload();
    130. } else {
    131. alert("评论发布失败")
    132. }
    133. })
    134. })
    135. // 获取用户名判断是否登录
    136. $.get(
    137. 'http://127.0.0.1/api/username',
    138. function(res) {
    139. // console.log(res);
    140. if (res.status == 200) {
    141. let username = res.username
    142. // 获取文章列表
    143. axios({
    144. method: 'GET',
    145. url: 'http://127.0.0.1/api/getlist',
    146. }).then(function(res) {
    147. // 将获取到的文章渲染到页面
    148. res.data.data.map(item => {
    149. $('.user').text(username)
    150. let li = `
  • ${item.content}
  • ${item.username}
  • `
  • $('.list-group').append(li)
  • })
  • })
  • } else {
  • alert('请先完成登录')
  • location.href = './login.html'
  • }
  • }
  • )
  • // 退出登录
  • $('#btnLogout').click(function() {
  • $.post(
  • 'http://127.0.0.1/api/register',
  • function(res) {
  • if (res.status == 200) {
  • // 如果 status 为 200,则表示退出成功,重新跳转到登录页面
  • location.href = './login.html'
  • }
  • }
  • )
  • })
  • })
  • script>
  • body>
  • html>
  • 五、展示个人博客页面

    登陆页面

    注册页面 

    博客主页 

      添加文章页面

    文章详细页面

    留言板 

    至此,我的个人博客大致完成,后续将会继续改进

  • 相关阅读:
    优酷新国风动漫《少年歌行海外仙山篇》开播,热血集结开启新冒险
    springboot实现websocket客户端断线重连
    来自阿里P8互联网面试官的夺命连环60问,Git命令面试简直是教科式天花板
    从源码角度分析Mybatis级联映射的实现原理
    C++异常处理的优缺点[重要]
    H3C 防火墙策略
    汇编-ARMv8架构指令集
    QQ恢复聊天记录,就用这3个方法!
    Django之图谱查询与标注平台
    神经网络中神经元的权重更新
  • 原文地址:https://blog.csdn.net/weixin_45932821/article/details/127854901