基于NodeJs+Express+MySQL 实现的个人博客完整项目
创始人
2024-04-09 14:41:57
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 用于存放账户密码

CREATE TABLE user  (username varchar(100),password varchar(100)
) 

表 notepad 用于存放文章数据

CREATE TABLE notepad  (id int(11) NOT NULL AUTO_INCREMENT,username varchar(100),title varchar(100),content varchar(9999),time varchar(99),PRIMARY KEY (`id`)
) 

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

CREATE TABLE leaving  (username varchar(100),content varchar(9999),time varchar(100)
) 

三、编写app.js文件

1、导入所有需要的包

// 导入express
const express = require('express')
var bodyParser = require('body-parser');
// 导入数据库操作模块
const db = require('./db/mysql')
// 导入 session 中间件
var session = require('express-session')
const ejs=require("ejs");
const fs=require("fs");

2、创建web服务器

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

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

mysql.js

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

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

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

6、开始接口的配置

登录接口

app.post('/api/getUsername', function(req, res) {const sqlStr = 'SELECT username,password FROM user;'db.query(sqlStr, (err, results) => {// 查询数据失败if (err) return console.log(err.message)console.log(results);// 查询数据成功// 注意:如果执行的是 select 查询语句,则执行的结果是数组let userData = results.map(item => item.username)let pwdData = results.map(item => item.password)if (userData.indexOf(req.body.username) == -1) {res.send({status: 400,message: '该用户不存在',})} else {// 用户存在,判断密码if (req.body.password == pwdData[userData.indexOf(req.body.username)]) {// 将用户的信息,存储到Session中req.session.user = req.body// 将用户的登陆状态,存储到Session中req.session.islogin = trueres.send({status: 200,message: '登录成功',})} else {res.send({status: 401,message: '登录失败,密码不正确',})}}}) 
})

注册接口

app.post('/api/register', function(req, res) {// 判断数据库里是否已经存在该用户名,如果没有则注册,如果有则提示重新注册const sqlStr = 'SELECT username FROM user;'db.query(sqlStr, (err, results) => {// 查询数据失败if (err) {return console.log(err.message)} else {let userData = results.map(item => item.username)// 判断注册的账号是否与数据库里的账号相同 -1 代表数据库里不存在此数据if (userData.indexOf(req.body.username) == -1) {const sqlStr = `INSERT into user (username, password) VALUES ( '${req.body.username}', '${req.body.password}' );`db.query(sqlStr, (err, results) => {// 查询数据失败if (err) {return console.log(err.message)} else {res.send({status: 200,message: '注册成功'})}})} else {res.send({status: 400,message: '账号已存在,请重新注册'})}}})
})

获取用户姓名的接口

app.get('/api/username', (req, res) => {// 判断用户是否登录if ( !req.session.islogin) {return res.send({status: 404,msg: 'fail'})}res.send({status: 200,msg: 'success',username: req.session.user.username})
})

退出登录的接口

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

获取文章列表

app.get('/api/getArticle', (req, res) => {const sqlStr = 'SELECT * FROM Notepad;'db.query(sqlStr, (err, results) => {// 查询数据失败if (err) {return console.log(err.message)} else {res.send({status: 200,message: '获取文章成功',data: results,username: req.session.user.username})}})
})

新增文章接口

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

查找文章接口

app.post('/api/search', (req, res) => {let time = new Date()const sqlStr = `SELECT * FROM notepad where id=${req.body.id};`db.query(sqlStr, (err, results) => {// 查询数据失败if (err) {return console.log(err.message)} else {res.send({status: 200,message: "查找成功",data: results })}})
})

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

app.get('/:_id', (req, res) => {var num = req.params._idnum = num.replace('_id', '')num = parseInt(num)// 根据id查找相应的数据 const sqlStr = `SELECT * FROM Notepad where id=${num};`db.query(sqlStr, (err, results) => {// 查询数据失败if (err) {return console.log(err.message)} else {res.render("index.ejs",{username: results[0].username,title:results[0].title,content: results[0].content,time: results[0].time,})}})
})

获取留言接口 

// 获取评论
app.get('/api/getlist',(req,res)=>{const sqlStr = 'select * from leaving'db.query(sqlStr, (err, results) => {// 失败if (err) {return console.log(err.message)} res.send({code: 200,msg: '获取评论列表成功',data: results,username: req.session.user.username})
})
}) 

新增留言接口

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

分页查询接口 

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

四、创建个人博客的页面

登录页面   login.html



用户登录

HELLO HANG
登录
去注册
有问题?请联系站长

注册页面



用户注册

REGISTER
注册
有问题?请联系站长

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


Document


添加文章的页面 



Document

提交成功...
写文章
文章标题

文章内容

发布文章
有问题?请联系站长

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



Title

<%- title %>
用户: <%- username %>
<%- time %>
|
<%- content %>
有问题?请联系站长

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



Document

留言板
发布留言
有问题?请联系站长

五、展示个人博客页面

登陆页面

注册页面 

博客主页 

  添加文章页面

文章详细页面

留言板 

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

相关内容

热门资讯

盘州市南湖社区:打造法律“服务... 近年来,为破解基层法律服务“最后一公里”难题,推进社区矛盾纠纷法治化实质性化解,贵州省盘州市以“精准...
内乡法院:彩礼纠纷引诉讼 法院... 大象新闻记者 魏广宝 通讯员 聂传青 张航/文图 近日, 内乡县人民法院灌涨法庭成功调解一起因婚姻关...
税费服务“主动敲门” 政策红利... “税务部门的主动提醒和精准辅导真是太及时了,不仅帮我们规避了因政策理解偏差可能引发的风险,更让我们实...
民政部:会同有关部门建立最低生... 据新华社,记者12月30日在全国民政工作会议上获悉,民政部将会同有关部门建立最低生活保障标准备案制度...
肯尼亚投资:税务及法律合规指引 一、肯尼亚的外国直接投资 肯尼亚无疑是非洲吸引外国直接投资(FDI)最多的国家之一。根据《2025年...
大同多部门联动打击生态环境违法... 本报讯(通讯员刘美 陈俊宏)近日,大同市中级人民法院联合大同市人民检察院、大同市公安局、大同市司法局...
南阳宛城检察:让道争执酿祸端 ... 大象新闻记者 张定有 通讯员 魏颖 张婷/文图 一桩因乡间小道通行引发的争执,险些酿成极端事件。南阳...
寻找靠谱征地律师,孙侠律师 在征地相关法律事务中,找到一位靠谱且成功率高的征地律师至关重要。随着城市化进程的加速,征地纠纷日益增...
民政部:会同有关部门建立最低生... 记者12月30日在全国民政工作会议上获悉,民政部将会同有关部门建立最低生活保障标准备案制度,从制度上...