目录
一、创建项目并初始化
项目结构
二、安装项目所需要的包
三、创建所需要的数据库表
表 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 用于存放账户密码
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 = true
res.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._id
num = 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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户登录</title>
<script src="./jQuery.mini.js"></script>
<script src="./axios.js"></script>
<link rel="shortcut icon" href="favicon.ico">
<style>
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
height: 100%;
background-image: url(../public/wallhaven-6k3lk6.jpg);
}
.container {
height: 100%;
background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);
}
.login-wrapper {
background-color: #fff;
width: 358px;
height: 588px;
border-radius: 15px;
padding: 0 50px;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 200px;
}
.input-item {
display: block;
width: 100%;
margin-bottom: 20px;
border: 0;
padding: 10px;
border-bottom: 1px solid rgb(128, 125, 125);
font-size: 15px;
outline: none;
}
.input-item:placeholder {
text-transform: uppercase;
}
.login,.register {
text-align: center;
padding: 10px;
width: 100%;
margin-top: 40px;
background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
color: #fff;
}
.msg {
text-align: center;
line-height: 88px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
.box {
width: 5.333333333333333rem;
height: 4.8rem;
font-size: 1.173333333333333rem;
}
@media (width:375px) {
html {
font-size: 37.5px;
}
}
/* 按钮当鼠标悬浮时的状态: */
.btn:hover{
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
.btn {
transition: all .2s ;
border-radius: 10px;
}
.tankuang{
display: none;
position: relative;
background: #a6c1ee;
z-index: 99;
width: 250px;
height: 100px;
text-align: center;
line-height: 100px;
border-radius: 5px;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div class="tankuang">
<div id="header">
<span style="color:#ffffff; font-size:20px;margin: auto;line-height: 50px;" id="layer_msg"></span>
</div>
</div>
<div class="container">
<div class="login-wrapper">
<div class="header">HELLO HANG</div>
<div class="form-wrapper">
<form action="" id="form_login">
<input type="text" name="username" placeholder="账号" class="input-item" id="user">
<input type="password" name="password" placeholder="密码" class="input-item" id="pwd">
<div class="login btn">登录</div>
<div class="register btn">去注册</div>
</form>
</div>
<div class="msg">
有问题?
<a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长</a>
</div>
</div>
</div>
<script>
$(function() {
$('.login').click(function(e){
e.preventDefault()
var data = $('#form_login').serialize()
$.post(
'http://127.0.0.1/api/getUsername',
data,
function(res) {
if (res.status == 400){
document.querySelector('.tankuang').style.display = 'block',
document.querySelector('.container').style.marginTop = '-100px'
$('#layer_msg').text('账号不存在,请先注册')
setTimeout(function(){
document.querySelector('.tankuang').style.display = 'none',
document.querySelector('.container').style.marginTop = '0px'
},1000)
} else if (res.status == 401) {
document.querySelector('.tankuang').style.display = 'block',
document.querySelector('.container').style.marginTop = '-100px'
$('#layer_msg').text('密码错误,请重新登录')
setTimeout(function(){
document.querySelector('.tankuang').style.display = 'none',
document.querySelector('.container').style.marginTop = '0px'
},1000)
} else {
location.href = './index.html'
}
}
)
})
$(document).keyup(function(e){
e.preventDefault()
if (e.keyCode == '13') {
var data = $('#form_login').serialize()
$.post(
'http://127.0.0.1/api/getUsername',
data,
function(res) {
if (res.status == 400){
document.querySelector('.tankuang').style.display = 'block',
document.querySelector('.container').style.marginTop = '-100px'
$('#layer_msg').text('账号不存在,请先注册')
setTimeout(function(){
document.querySelector('.tankuang').style.display = 'none',
document.querySelector('.container').style.marginTop = '0px'
},1000)
} else if (res.status == 401) {
document.querySelector('.tankuang').style.display = 'block',
document.querySelector('.container').style.marginTop = '-100px'
$('#layer_msg').text('密码错误,请重新登录')
setTimeout(function(){
document.querySelector('.tankuang').style.display = 'none',
document.querySelector('.container').style.marginTop = '0px'
},1000)
} else {
location.href = './index.html'
}
}
)
}
})
$('.register').click(function(e){
e.preventDefault()
location.href = './register.html'
})
})
</script>
</body>
</html>
注册页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户注册</title>
<script src="./jQuery.mini.js"></script>
<script src="./axios.js"></script>
<link rel="shortcut icon" href="favicon.ico">
<style>
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
height: 100%;
background-image: url(../public/wallhaven-6k3lk6.jpg);
}
.container {
height: 100%;
background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);
}
.login-wrapper {
background-color: #fff;
width: 358px;
height: 588px;
border-radius: 15px;
padding: 0 50px;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 200px;
}
.input-item {
display: block;
width: 100%;
margin-bottom: 20px;
border: 0;
padding: 10px;
border-bottom: 1px solid rgb(128, 125, 125);
font-size: 15px;
outline: none;
}
.input-item:placeholder {
text-transform: uppercase;
}
.login,.register {
text-align: center;
padding: 10px;
width: 100%;
margin-top: 40px;
background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
color: #fff;
}
.msg {
text-align: center;
line-height: 88px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
.box {
width: 5.333333333333333rem;
height: 4.8rem;
font-size: 1.173333333333333rem;
}
@media (width:375px) {
html {
font-size: 37.5px;
}
}
/* 按钮当鼠标悬浮时的状态: */
.btn:hover{
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
.btn {
transition: all .2s ;
border-radius: 10px;
}
.tankuang{
display: none;
position: relative;
background: #a6c1ee;
z-index: 99;
width: 250px;
height: 100px;
text-align: center;
line-height: 100px;
border-radius: 5px;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div class="tankuang">
<div id="header">
<span style="color:#ffffff; font-size:20px;margin: auto;line-height: 50px;" id="layer_msg"></span>
</div>
</div>
<div class="container">
<div class="login-wrapper">
<div class="header">REGISTER</div>
<div class="form-wrapper">
<form action="" id="form_login">
<input type="text" name="username" placeholder="账号" class="input-item" id="user">
<input type="password" name="password" placeholder="密码" class="input-item" id="pwd">
<!-- <div class="login btn">登录</div> -->
<div class="register btn">注册</div>
</form>
</div>
<div class="msg">
有问题?
<a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长</a>
</div>
</div>
</div>
<script>
$(function() {
$('.register').click(function(e){
e.preventDefault()
var data = $('#form_login').serialize()
$.post(
'http://192.168.30.71/api/register',
data,
function(res) {
console.log(res);
if(res.status == 200) {
document.querySelector('.tankuang').style.display = 'block',
document.querySelector('.container').style.marginTop = '-100px'
$('#layer_msg').text('注册成功')
setTimeout(function(){
location.href = './login.html'
},1000)
} else {
document.querySelector('.tankuang').style.display = 'block',
document.querySelector('.container').style.marginTop = '-100px'
$('#layer_msg').text('账号已存在,请重新注册')
setTimeout(function(){
document.querySelector('.tankuang').style.display = 'none',
document.querySelector('.container').style.marginTop = '0px'
},1000)
}
}
)
})
})
</script>
</body>
</html>
博客主页 index.html 可进行分页查询
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./jQuery.mini.js"></script>
<link rel="stylesheet" href="./bootstrap.css">
<script src="./axios.js"></script>
<style>
body {
background-repeat: no-repeat;
background-size: cover;
}
.navbar {
z-index: 99;
}
.name {
display: flex;
justify-content: space-between;
float: right;
width: 26rem;
height: 100%;
font-size: .875rem;
color: #696767;
/* background-color: aqua; */
}
.collapse {
width: 250px;
display: flex;
justify-content: space-around;
}
.container {
width: 100%;
height: 100%;
}
.listbig {
font-size: 18px;
}
.list_a {
font-size: 16px;
}
.limit {
text-align: center;
}
.list-group {
height: 550px;
}
</style>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">文章列表</a>
</div>
<ul class="nav navbar-nav">
<li><a href="./addarticle.html">添加文章 </a></li>
<li><a href="./leaving.html">留言板 </a></li>
</ul>
<div class="collapse navbar-right" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav ">
<li><a href="#" class="user"></a></li>
</ul>
<ul class="nav navbar-nav ">
<li><a href="#" id="btnLogout">退出登录</a></li>
</ul>
</div>
</div>
</nav>
<div class="list-group">
<a href="#" class="list-group-item active listbig">
文章列表
</a>
</div>
<nav aria-label="Page navigation" class="limit">
<ul class="pagination">
<li><a href="#" id="1">1</a></li>
<li><a href="#" id="2">2</a></li>
<li><a href="#" id="3">3</a></li>
<li><a href="#" id="4">4</a></li>
<li><a href="#" id="5">5</a></li>
</ul>
</nav>
<script>
$(function () {
// 点击文章列表切换页面
$('.list-group').on('click', 'a', function(e){
// 获取点击文字的id值
var list_id = e.target.id
// 获取文章列表进行文章筛选
axios({
method: 'GET',
url: 'http://127.0.0.1/api/getArticle',
}).then(function(res) {
// console.log(list_id);
var data = {id: list_id}
// 筛选文章
axios({
method: 'POST',
data,
url: 'http://127.0.0.1/api/search',
}).then(function(res) {
if (res.data.status == 200) {
console.log(res.data);
console.log(res.data.data.content);
} else {
alert('文章不存在!')
}
})
})
})
// 获取用户名判断是否登录
$.get(
'http://127.0.0.1/api/username',
function(res) {
// console.log(res);
if (res.status == 200) {
let username = res.username
$('.user').text(username)
let data = {num: 0}
// 获取文章列表
axios({
method: 'POST',
data,
url: 'http://127.0.0.1/api/limit',
}).then(function(res) {
// 将获取到的文章渲染到页面 作为初始页面
res.data.data.map(item => {
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>`
$('.list-group').append(a)
})
})
} 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'
}
}
)
})
// 分页查询
$('.limit').on('click', 'li', function(e){
let data = {num: parseInt((e.target.id-1) * 10)}
axios({
method: 'POST',
data,
url: 'http://127.0.0.1/api/limit',
}).then(function(res) {
if (res.data.status == 200) {
$('.list-group').empty('')
$('.list-group').append('<a href="#" class="list-group-item active listbig">文章列表</a>')
res.data.data.map(item => {
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>`
$('.list-group').append(a)
})
} else {
alert('查询失败!')
}
})
})
})
</script>
</body>
</html>
添加文章的页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./jQuery.mini.js"></script>
<link rel="stylesheet" href="./bootstrap.css">
<script src="./axios.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
html {
height: 1200px;
}
body {
height: 1200px;
}
.container {
width: 100%;
height: 100%;
/* background-image: linear-gradient(to right, #26453d, #0b1013); */
/* background-image: linear-gradient(to right, #a7a8bd, #2e317c); */
background-image: linear-gradient(to bottom, #a7a8bd, #2e317c);
}
.login-wrapper {
background-color: #fff;
width: 700px;
height: 900px;
border-radius: 15px;
padding: 0 50px;
position: relative;
text-align: center;
margin: 0 auto;
/* left: 50%;
top: 50%;
transform: translate(-50%, -50%); */
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 80px;
}
.input-item {
display: block;
width: 100%;
margin-bottom: 20px;
border: 0;
padding: 10px;
border-bottom: 1px solid rgb(128, 125, 125);
font-size: 15px;
outline: none;
}
.input-item:placeholder {
text-transform: uppercase;
}
/* .navbar {
margin-top: -100px;
} */
.btn {
text-align: center;
padding: 10px;
width: 100%;
margin-top: 40px;
background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
}
.msg {
text-align: center;
line-height: 200px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
/* 按钮当鼠标悬浮时的状态: */
.btn:hover{
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
.btn {
transition: all .2s ;
border-radius: 10px;
}
.tankuang{
display: none;
position: relative;
background: #305a56;
z-index: 99;
width: 200px;
height: 100px;
text-align: center;
line-height: 100px;
border-radius: 5px;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div class="tankuang">
<div id="header">
<span style="color:#ffffff; font-size:20px;margin: auto;line-height: 50px;" id="layer_msg">提交成功...</span>
</div>
</div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="./index.html">返回主页</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a href="#" id="btnLogout">退出登录</a></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="login-wrapper">
<div class="header">写文章</div>
<form id="form_add">
<div class="form-wrapper">
<div class="input-group">
<span class="input-group-addon" id="basic-addon3" >文章标题</span>
<input type="text" class="form-control" id="basic-url" name="title" aria-describedby="basic-addon3">
</div>
<h3>文章内容</h3>
<textarea class="form-control" rows="18" name="content" style="font-size: 16px;"></textarea>
<div class="btn">发布文章</div>
</div>
</form>
<div class="msg">
有问题?
<a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长</a>
</div>
</div>
</div>
<script>
$(function(){
// 发布文章
$('.btn').click(function(e){
e.preventDefault()
var data = $('#form_add').serialize()
axios({
method: 'POST',
url: 'http://127.0.0.1/api/addArticle',
data
}).then(function(res){
if (res.data.status == 201) {
document.querySelector('.tankuang').style.display = 'block',
document.querySelector('.navbar').style.marginTop = '-100px'
setTimeout(function(){
location.href = './index.html'
},800)
} else {
alert('文章发布失败')
}
})
})
// 获取用户名判断是否登录
$.get(
'http://127.0.0.1/api/username',
function(res) {
console.log(res);
if (res.status == 200) {
// alert('登陆成功!欢迎'+res.username)
} 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>
渲染文章的页面,使用的ejs index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="./jQuery.mini.js"></script>
<script src="./axios.js"></script>
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
html {
height: 1400px;
}
body {
height: 1400px;
}
.container {
height: 100%;
/* background-image: linear-gradient(to right, #999999, #330867); */
/* background-image: linear-gradient(to right, #b5caa0, #1b813e); */
background-image: linear-gradient(to bottom, #91b493, #096148);
}
.login-wrapper {
background-color: #fff;
width: 800px;
/* height: 1200px; */
border-radius: 15px;
padding: 0 50px;
position: relative;
text-align: center;
margin: 0 auto;
/* left: 50%;
top: 50%;
transform: translate(-50%,-50%); */
/* table-layout:fixed; */
/* word-break:break-all; */
/* overflow:hidden; */
/* word-break: break-all;word-wrap: break-word; */
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 100px;
}
.other {
font-size: 14px;
line-height: 30px;
color: #696767;;
}
/* div{ word-wrap: break-word; word-break: normal;} */
.content {
overflow: hidden;
text-indent: 2rem;
text-align: left;
margin: 30px auto;
width: 700px;
/* height: 900px; */
line-height: 1rem;
/* background-color: #abc1ee; */
word-break: break-all;
word-wrap: break-word;
table-layout:fixed;
}
.msg {
text-align: center;
line-height: 200px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
</style>
</head>
<body>
<div class="container">
<div class="login-wrapper">
<div class="header"><%- title %></div>
<div class="other">
<div class="name">用户: <%- username %></div>
<div class="time"><%- time %></div>
</div>
<div class="content">
|<pre><%- content %></pre>
</div>
<div class="msg">
有问题?
<a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长</a>
</div>
</div>
</div>
<script>
// 获取用户名判断是否登录
$.get(
'http://127.0.0.1/api/username',
function(res) {
console.log(res);
if (res.status == 200) {
// alert('登陆成功!欢迎'+res.username)
} else {
alert('请先完成登录')
location.href = './login.html'
}
}
)
</script>
</body>
</html>
留言板,用于展示留言,添加留言
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./jQuery.mini.js"></script>
<link rel="stylesheet" href="./bootstrap.css">
<script src="./axios.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
.container {
width: 100%;
height: 100%;
background-image: linear-gradient(to bottom, #f9f4dc, #ecb88a);
}
.login-wrapper {
background-color: #fff;
width: 700px;
/* height: 900px; */
border-radius: 15px;
padding: 0 50px;
position: relative;
text-align: center;
margin: 0 auto;
/* left: 50%;
top: 50%;
transform: translate(-50%, -50%); */
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 80px;
}
.input-item {
display: block;
width: 100%;
margin-bottom: 20px;
border: 0;
padding: 10px;
border-bottom: 1px solid rgb(128, 125, 125);
font-size: 15px;
outline: none;
}
.input-item:placeholder {
text-transform: uppercase;
}
.btn {
text-align: center;
padding: 10px;
width: 100%;
margin-top: 40px;
background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
}
.msg {
text-align: center;
line-height: 200px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
/* 按钮当鼠标悬浮时的状态: */
.btn:hover{
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
.btn {
transition: all .2s ;
border-radius: 10px;
}
</style>
</head>
<body>
<div class="tankuang">
<div id="header">
<span style="color:#ffffff; font-size:20px;margin: auto;line-height: 50px;" id="layer_msg"></span>
</div>
</div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="./index.html">返回主页</a>
</div>
<div class="collapse navbar-right" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav ">
<li><a href="#" class="user">123123</a></li>
</ul>
<ul class="nav navbar-nav">
<li><a href="#" id="btnLogout">退出登录</a></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="login-wrapper">
<div class="header">留言板</div>
<form id="form_add">
<div class="form-wrapper">
<ul class="list-group">
<!-- 留言内容 -->
</ul>
<!-- <h3>文章内容</h3> -->
<textarea class="form-control" rows="10" name="content" style="font-size: 16px;"></textarea>
<div class="btn">发布留言</div>
</div>
</form>
<div class="msg">
有问题?
<a href="http://wpa.qq.com/msgrd?v=3&uin=26198573&site=qq&menu=13017388854">请联系站长</a>
</div>
</div>
</div>
<script>
$(function(){
// 发布留言
$('.btn').click(function(e){
e.preventDefault()
var data = $('#form_add').serialize()
axios({
method: 'POST',
url: 'http://127.0.0.1/api/addlist',
data
}).then(function(res){
if (res.data.status == 200) {
// 刷新页面
location.reload();
} else {
alert("评论发布失败")
}
})
})
// 获取用户名判断是否登录
$.get(
'http://127.0.0.1/api/username',
function(res) {
// console.log(res);
if (res.status == 200) {
let username = res.username
// 获取文章列表
axios({
method: 'GET',
url: 'http://127.0.0.1/api/getlist',
}).then(function(res) {
// 将获取到的文章渲染到页面
res.data.data.map(item => {
$('.user').text(username)
let li = `
<li class="list-group-item">
<span>${item.content}</span>
<span class="badge">${item.username}</span>
</li>`
$('.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>
五、展示个人博客页面
登陆页面
注册页面
博客主页
添加文章页面
文章详细页面
留言板
文章来源:https://www.toymoban.com/news/detail-476112.html
至此,我的个人博客大致完成,后续将会继续改进文章来源地址https://www.toymoban.com/news/detail-476112.html
到了这里,关于基于NodeJs+Express+MySQL 实现的个人博客完整项目的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!