从0开始搭建Vue博客——ch2后端初始化

在上一节中我们完成了前端的初始化,下面来进行后端框架的搭建。

在这里我们选择的框架是基于nodejs的Express,简单灵活学习成本低。

express提供了路由和中间件的核心功能。路由是可以按照不同路径来调用不同的后端服务,中间件可以拦截请求进行各种校验。之前没接触过,在这顺手学一下。

初始化

首先创建一个工程目录,就命名为vueblog_backend。进入目录命令行输入初始化命令npm init,就会出现一个json文件,然后就是引入框架npm install express即可。

下面我们来创建一个简单的接口来测试一下。

js 复制代码
app.js
// 引入express模块
const express = require('express')

// 创建express实例并设置端口号
const app = express()
const port = 3000

// 设置响应某个路由时执行的操作
// 这里是用get方法访问测试路由时向前端发送Hello World!
app.get('/test', (req, res) => {
    res.send('Hello World!')
})

// 监听端口,也就是开启后端
app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})

在终端运行node app.js,再在浏览器访问localhost:3000测试get请求,就可以看到网页上显示helloworld! 但是如果代码有变化,每次都需要ctrl+c关闭服务器再重启,很不方便。

我们下载一个插件nodemon,就可以自动检测工作区的变化并自动重启了。执行npm install nodemon --save-dev,再把package.json里的start命令改为"start": "nodemon app.js"

这样只要在终端执行npm run start,就能得到自动更新的服务器和页面啦!

传参

前端和后端是如何传递参数的呢?其实就是通过一些请求,GET、POST、PUT之类的。前端向某个路由发出请求,传递req给后端,后端根据接口返回res给前端。

query传参

将请求参数放在URL中 传递的方式,请求参数是键值对,和URL用?分隔,多个参数间使用&分隔。GET 请求只能传query参数。

传入的参数会在req.query中被拦截,因此可以获取相应的参数。比如下面的例子,访问localhost:3000/test?username=1就可以在页面上看到被传入的参数1

js 复制代码
app.get('/test',(req, res)=>{
    res.send(`${req.query.username}`);
})

body传参

body传参是通过请求的主体部分 传递的数据,通常用于传递较大的数据,比如JSON和XML格式。常与POST或PUT请求一起用。

js 复制代码
// 引入express模块
const express = require('express')
// 引入body-parser模块,用于处理请求体数据
const bodyParser = require('body-parser')

// 创建express实例并设置端口号
const app = express()
const port = 3000

// body-parser模块作为插件挂载到express实例上,有json就够用
app.use(bodyParser.json())

// 用post方法访问注册路由时的操作
app.post('/register', (req, res)=> {
    const username = req.body.username
    res.send(`注册成功,用户名为${username}`)
})

// 监听端口,也就是开启后端
app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})

使用postman来模拟post请求,输入请求地址,选择body,raw,json。发现可以正常响应。

路由

路由是个什么东西呢?说白了就是平时上网冲浪的网址域名后面的部分。比如https://www.bilibili.com/video/BVxxxxx,video就是路由。上面我们写的test、register也是接口的路由。根据不同的url请求,服务器返回不同的内容。

如果想要访问多个有相似路径的url,比如user/register,user/login,就得这样写:

js 复制代码
app.get('/user/register', (req, res) => {
    res.send('注册接口')
})。
app.get('/user/login', (req, res) => {
    res.send('登录接口')
})。

很啰嗦,也不好直观地看出接口的功能。那么我们可以使用路由分发(也是路由模块化的基础)。格式如下:

js 复制代码
// 路由拆分
// 先注册路由
const user = express.Router()
app.use('/user', user)

// 再使用路由
user.get('/register', (req, res) => {
    res.send('注册接口')
})

user.get('/login', (req, res) => {
    res.send('登录接口')
})

路由模块化

如果我们要实现很多个功能,总不能把所有路由都写在app.js里吧,臃肿又不方便。

这时候就涉及到了路由模块化。新建一些js文件,把相关路由写在里面并导出,最后在app.js里引入就可以了

js 复制代码
register.js
const express = require('express') // 引入express模块
const SHA512 = require('crypto-js/sha512') // 引入crypto-js模块,用于加密密码

var router = express.Router() // 创建子路由
// 挂载具体的路由
router.post('/register',(req, res)=>{
    const username = req.body.username;
    let password = req.body.password;
    password = SHA512(password).toString();
    res.send(username);
})
module.exports = router; // 导出路由
js 复制代码
app.js
const useRegister = require('./register/register.js') // 引入子路由
app.use('/', useCreateDatabase) // 注册子路由,参数是路径前缀和子路由,前缀也可以不加

然后就可以用/register访问接口了

即使如此,也还是要在app.js里写很多引入注册子路由的语句,有没有更简洁的办法呢?当然是有的!

我们可以把子路由的引入与注册写成一个合集,在app.js里引入这个合集就好了

js 复制代码
index.js
// 引入数据库创建子路由
const useCreateDatabase = require('../createDatabase/createDatabase.js')
// 引入注册子路由
const useRegister = require('../register/register.js')
// 引入日志中间件
const useLogger = require('../middleware/logger.js')

module.exports = app => { // 导出函数
// 注册子路由,参数是路径前缀和子路由,前缀也可以不加
app.use('/', useCreateDatabase)
app.use(useRegister)
app.use(useLogger)
}
js 复制代码
app.js
// 引入路由集合模块并调用函数
const routes = require('./routes')
routes(app);

现在我们的项目结构是这样的:

中间件

中间件其实就是自己定义的函数,在访问路由时执行。相比于路由,多了一个next参数,有全局中间件和路由中间件

全局中间件

顾名思义,用户发起任何请求都会执行的中间件。使用之前要使用use函数注册

js 复制代码
// 全局中间件
// 定义全局中间件
function middleWare(req, res, next) {
    console.log('这是全局中间件')
    next()
}
// 注册全局中间件
app.use(middleWare)
// 定义路由,会自动使用全局中间件
app.get('/test1', (req, res) => {   // 或者写成function(req, res) {}
    res.send('test1')
})

可以看到,访问路由时自动执行了middleware的内容

路由中间件

顾名思义,路由中间件就是在某个特定路由中执行的中间件。需要在该路由的参数里插入这个中间件

js 复制代码
// 路由中间件,在路由地址和路由处理函数之间定义中间件
app.get('/test2', function(req, res, next) {
    console.log('这是路由中间件')
    next()
    }, (req, res) => {
        res.send('test2')
})

由于我们之前注册了全局中间件,所以在执行这个路由的时候也会执行middleware

日志中间件

如果我们想打印每次操作的日志,应该怎么办呢?当然是使用全局中间件!不过这次就不写在app.js里了,写在单独的日志文件logger.js里(不要忘记导出)。

js 复制代码
// 定义日志中间件
function logger(req, res, next) {
    const time = new Date()
    console.log(`[${time.toLocaleString()}] ${req.method} ${req.url}`)
    next()
}

// 导出日志中间件
module.exports = logger
js 复制代码
app.js
// 引入并注册日志中间件
const logger = require('./middleware/logger.js')
app.use(logger)

app.get('/test3', (req, res) => {
    res.send('test3')
})

可以看到还是非常成功的

数据库

项目写好了需要部署,我在阿里云买了云服务器,操作系统选择的Debian,连接上宝塔面板,数据库选择的是MySQL,网上有很多部署相关教程。博主数据库学得一般,相关语句也是参考的网上教程

前期需要做的就是连接数据库并建表。

js 复制代码
createDatabase.js
const express = require('express') // 引入express模块
const mysql = require('mysql') // 引入mysql模块
var router = express.Router() // 创建子路由

// 连接远程数据库
const connection = mysql.createConnection({
    host: 'xxx.xxx.xxx.xxx', // 数据库的地址,我们这里是连接到服务器的数据库
    user: 'root', // 用户名和密码,我们这里使用管理员用户
    password: 'admin',
    port: 3306, // 端口号,默认是3306
    database: 'userdata' // 所连接的数据库名称,userdata数据库是之前在宝塔面板中创建好的
})
connection.connect(); // 连接数据库

// 建表
router.get('/createDatabase',(req, res)=>{
    connection.query(`create table useraccount
                    (
                        username varchar(20),
                        password varchar(512)
                    )`,
    (err,res)=>{
        console.log(err);
    });
})

module.exports = router; // 导出路由

再写一个注册路由,需要对用户名进行去重并对密码进行加密后加入数据库

js 复制代码
const express = require('express') // 引入express模块
const SHA512 = require('crypto-js/sha512') // 引入crypto-js模块,用于加密密码
const mysql = require('mysql') // 引入mysql模块
var router = express.Router() // 创建子路由

// 连接远程数据库
const connection = mysql.createConnection({
    host: 'xxx.xxx.xxx.xxx', // 数据库的地址,我们这里是连接到服务器的数据库
    user: 'root', // 用户名和密码,我们这里使用管理员用户
    password: 'admin',
    port: 3306, // 端口号,默认是3306
    database: 'userdata' // 所连接的数据库名称,userdata数据库是之前在宝塔面板中创建好的
})
connection.connect(); // 连接数据库

// 注册,加密去重
router.post('/register',(req, res)=>{
    const username = req.body.username;
    let password = req.body.password;
    password = SHA512(password).toString();
    const addSql=`insert into useraccount (username, password) values(?,?)`;
    const selectSql = `select * from useraccount where username = '${username}'`;
    connection.query(selectSql,(err,result)=>{
        console.log(result);
        if(result.length!==0){
            res.status(400).send('用户名已存在');
        }else{
            connection.query(addSql,[username, password],(err)=>{
            if(err){
                res.status(500).send(`注册失败, ${err}`);
            }else{
                res.send('注册成功');
            }
    })
        }
    })
})

module.exports = router; // 导出路由

到此为止,我们的前后端初始化就完成了,但是博主的服务器只连接了数据库,还没部署nodejs,打算等完善好再打包上线

相关推荐
USER_A0013 天前
【Node.js】express框架
node.js·express
難釋懷6 天前
前后端的身份认证
node.js·express
前端Kingtato7 天前
Node.js中Express框架使用指南:从入门到企业级实践
node.js·express
yqcoder8 天前
Express 中间件是什么
中间件·express
℡52Hz★9 天前
Node.js中express框架(三)
node.js·express
難釋懷10 天前
Express 中间件
中间件·express
m0_7482466112 天前
使用Node.js搭配express框架快速构建后端业务接口模块Demo
node.js·express
摆烂式编程14 天前
node.js 08 express的使用和热重载nodemon的安装
node.js·express
Мартин.15 天前
[Meachines] [Easy] Nunchucks Express Nodejs SSTI+AppArmor Bypass+Perl权限提升
开发语言·express·perl