小言_互联网的博客

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

685人阅读  评论(0)

目录

一、创建项目并初始化

项目结构

二、安装项目所需要的包

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

表 user 用于存放账户密码

表 notepad 用于存放文章数据

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

三、编写app.js文件

1、导入所有需要的包

2、创建web服务器

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

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

6、开始接口的配置

四、创建个人博客的页面

五、展示个人博客页面

实现的功能: 多用户登录,注册,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. <!DOCTYPE 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 HANG </div>
  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. <!DOCTYPE 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">REGISTER </div>
  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. $( '.register'). click( function( e){
  134. e. preventDefault()
  135. var data = $( '#form_login'). serialize()
  136. $. post(
  137. 'http://192.168.30.71/api/register',
  138. data,
  139. function( res) {
  140. console. log(res);
  141. if(res. status == 200) {
  142. document. querySelector( '.tankuang'). style. display = 'block',
  143. document. querySelector( '.container'). style. marginTop = '-100px'
  144. $( '#layer_msg'). text( '注册成功')
  145. setTimeout( function( ){
  146. location. href = './login.html'
  147. }, 1000)
  148. } else {
  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. }
  157. }
  158. )
  159. })
  160. })
  161. </script>
  162. </body>
  163. </html>

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


  
  1. <!DOCTYPE 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>Document </title>
  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">1 </a> </li>
  79. <li> <a href="#" id="2">2 </a> </li>
  80. <li> <a href="#" id="3">3 </a> </li>
  81. <li> <a href="#" id="4">4 </a> </li>
  82. <li> <a href="#" id="5">5 </a> </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. let a = `<a href="${item.id}_id" target="_blank" class="list-group-item list_a" id="${item.id}">${item.title} <div class="name"> <span class="username">用户 ${item.username}</span> <span class="time">发布于 ${item.time}</span></div> </a>`
  131. $( '.list-group'). append(a)
  132. })
  133. })
  134. } else {
  135. alert( '请先完成登录')
  136. location. href = './login.html'
  137. }
  138. }
  139. )
  140. // 退出登录
  141. $( '#btnLogout'). click( function( ) {
  142. $. post(
  143. 'http://127.0.0.1/api/register',
  144. function( res) {
  145. if (res. status == 200) {
  146. // 如果 status 为 200,则表示退出成功,重新跳转到登录页面
  147. location. href = './login.html'
  148. }
  149. }
  150. )
  151. })
  152. // 分页查询
  153. $( '.limit'). on( 'click', 'li', function( e){
  154. let data = { num: parseInt((e. target. id- 1) * 10)}
  155. axios({
  156. method: 'POST',
  157. data,
  158. url: 'http://127.0.0.1/api/limit',
  159. }). then( function( res) {
  160. if (res. data. status == 200) {
  161. $( '.list-group'). empty( '')
  162. $( '.list-group'). append( '<a href="#" class="list-group-item active listbig">文章列表</a>')
  163. res. data. data. map( item => {
  164. let a = `<a href="${item.id}_id" target="_blank" class="list-group-item list_a" id="${item.id}">${item.title} <div class="name"> <span class="username">用户 ${item.username}</span> <span class="time">发布于 ${item.time}</span></div> </a>`
  165. $( '.list-group'). append(a)
  166. })
  167. } else {
  168. alert( '查询失败!')
  169. }
  170. })
  171. })
  172. })
  173. </script>
  174. </body>
  175. </html>

添加文章的页面 


  
  1. <!DOCTYPE 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>Document </title>
  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. <!DOCTYPE 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>Title </title>
  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. <!DOCTYPE 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>Document </title>
  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">123123 </a> </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. <!-- 留言内容 -->
  106. </ul>
  107. <!-- <h3>文章内容</h3> -->
  108. <textarea class="form-control" rows="10" name="content" style="font-size: 16px;"> </textarea>
  109. <div class="btn">发布留言 </div>
  110. </div>
  111. </form>
  112. <div class="msg">
  113. 有问题?
  114. <a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长 </a>
  115. </div>
  116. </div>
  117. </div>
  118. <script>
  119. $( function( ){
  120. // 发布留言
  121. $( '.btn'). click( function( e){
  122. e. preventDefault()
  123. var data = $( '#form_add'). serialize()
  124. axios({
  125. method: 'POST',
  126. url: 'http://127.0.0.1/api/addlist',
  127. data
  128. }). then( function( res){
  129. if (res. data. status == 200) {
  130. // 刷新页面
  131. location. reload();
  132. } else {
  133. alert( "评论发布失败")
  134. }
  135. })
  136. })
  137. // 获取用户名判断是否登录
  138. $. get(
  139. 'http://127.0.0.1/api/username',
  140. function( res) {
  141. // console.log(res);
  142. if (res. status == 200) {
  143. let username = res. username
  144. // 获取文章列表
  145. axios({
  146. method: 'GET',
  147. url: 'http://127.0.0.1/api/getlist',
  148. }). then( function( res) {
  149. // 将获取到的文章渲染到页面
  150. res. data. data. map( item => {
  151. $( '.user'). text(username)
  152. let li = `
  153. <li class="list-group-item">
  154. <span>${item.content}</span>
  155. <span class="badge">${item.username}</span>
  156. </li>`
  157. $( '.list-group'). append(li)
  158. })
  159. })
  160. } else {
  161. alert( '请先完成登录')
  162. location. href = './login.html'
  163. }
  164. }
  165. )
  166. // 退出登录
  167. $( '#btnLogout'). click( function( ) {
  168. $. post(
  169. 'http://127.0.0.1/api/register',
  170. function( res) {
  171. if (res. status == 200) {
  172. // 如果 status 为 200,则表示退出成功,重新跳转到登录页面
  173. location. href = './login.html'
  174. }
  175. }
  176. )
  177. })
  178. })
  179. </script>
  180. </body>
  181. </html>

五、展示个人博客页面

登陆页面

注册页面 

博客主页 

  添加文章页面

文章详细页面

留言板 

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


转载:https://blog.csdn.net/weixin_45932821/article/details/127854901
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场