农妇山泉一亩田 发表于 2025-2-21 09:49:22

expres搭建一个基本的web网站服务器详细步调

前言

express是基于Nodejs平台快速开放极简的web开发框架,它可以用来搭建web网站服务器或者api接口服务器,本文将详细列出利用express搭建一个web网站服务器的利用步调,其中包含一些搭建服务器过程中涉及到的Node.js相干的底子知识,接待各人一起来学习和讨论。
一、快速创建包管理配置文件

包管理配置文件里清楚的记录项目中安装了哪些包,此文件在开发情况中是必不可少的。准备一个文件夹存放项目文件,利用开发工具vscode打开项目文件夹,打开终端运行如下代码:
1、package.json

//快速创建包管理配置文件 package.json
npm init -y
2、node_modules

node_modules文件夹中存放与项目有关的所有的包,此时运行以下命令,项目中还不会生成node_modules,而是生成了 package-lock.json,后续添加项目相干包就会主动生成node_modules了。
npm install
二、创建基本的web服务器

1、安装express

安装express命令如下:
npm install
express 安装完成后,项目根目录创建app.js文件,在 package.json中修改main入口文件为 app.js。如下图所示:
https://i-blog.csdnimg.cn/direct/188f22223e6443f5b92d5a9dd3b02cdb.jpeg#pic_center
2、创建服务器

app.js添加代码,创建一个基本的web服务器。
// 导入express
const express = require('express')

// 创建web服务器
const app = express()

// 启动web服务器
app.listen(3380,()=>{
    console.log('server run at http://127.0.0.1:3380');
})
3、启动服务器

打开终端运行启动服务器,命令如下:
node ./app.js
三、托管静态资源

1、调用express.static()

1.项目根目录下新建public文件夹,public文件夹下新建css(存放css相干样式文件)、images(存放图片相干)、js(存放js代码相干)文件夹 和index.html(用于启动服务器展示页)文件。
//index.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>web服务器</title>
</head>
<body>
    <div>welcome to access web service...</div>
</body>
</html>
2.app.js中调用express.static()托管静态资源
// 托管静态资源
app.use(express.static('./public'))
3.项目有改动,重启服务器node ./app.js
,浏览器访问地址:http://127.0.0.1:3380/ ,页面可以看到index.html的内容,分析托管静态资源配置乐成。
2、托管多个静态资源

如果要托管多个静态资源目录,请多次调用express.static()函数,当访问静态资源文件时,express.static()函数会根据添加的顺序查找所需文件。
例如:
//确保项目中有文件 public 和 upload
app.use(express.static('./public'))
app.use(express.static('./upload'))
3、挂载路径前缀

如果希望在托管的静态资源访问路径之前,挂载路径前缀,则可以利用如下方式:
app.use('/public',express.static('./public'))
以上配置好之后就可以通过带有/public前缀的地址来访问public目录文件了,访问的地址示例:
http://127.0.0.1:3380/public/index.html
四、nodemon工具

1、为什么利用nodemon

nodemon可以监听项目文件的变动,当代码被修改,nodemon会主动资助我们重启项目,进步了开发效率。
2、安装nodemon

在终端中,运行如下命令,即可将nodemon安装为全局可用的工具:
npm install
-g nodemon 3、利用nodemon

在没有安装nodemon之前,启动项目利用node ./app.js

如今安装了nodemon,将启动命令更换为:
nodemon ./app.js
五、 express路由

在express中,路由指的是客户端的请求与服务器处理函数之间的映射关系。express中的路由分3个部门组成,分别是请求的类型、请求的URL地址、处理函数。利用路由最基本的方式就是挂载到app身上。格式如下:
app.METHOD(PATH,HANDLER)
模块化路由

express不建议将路由直接挂载到app上,推荐将路由抽离为单独的模块。将路由抽离为单独模块的步调如下:
1.创建对应的.js路由模块文件
2.调用express.Router()创建路由对象
3.向路由对象上挂载详细的路由
4.利用module.exports向外共享路由对象
5.入口文件中利用app.use()注册路由模块
1、 创建用户路由模块

下面抽离用户路由模块的示例:
根目录下新建用户路由模块/router/user.js 示例代码如下:
// 导入express
const express = require('express')
// 创建路由对象
const router = express.Router()

// 导入路由处理函数
const userRouterHandler = require('../router_handler/user')

// 获取用户列表的路由
router.get('/userlist',userRouterHandler.getUserListHandle)

// 更新用户信息的路由
router.put('/userinfo',userRouterHandler.updateUserInfoHandle)

// 向外导出路由对象
module.exports = router
根目录下新建用户路由处理函数 /router_handler/user.js 示例代码如下:
// 获取用户信息路由处理函数
exports.getUserListHandle = (req,res)=>{
    // 相关逻辑...
    res.send('ok')
}

// 更新用户信息路由处理函数
exports.updateUserInfoHandle = (req,res)=>{
    // 相关逻辑...
    res.send('ok')
}
在入口文件app.js导入并注册用户路由模块,示例代码如下:
// 导入并注册用户路由模块
const userRouter = require('./router/user')
//根据需求配置路由前缀 /api
app.use('/api',userRouter)
2、启动测试

nodemon ./app.js
启动项目
利用api接口测试工具(这里利用Postman) 测试接口 :
http://127.0.0.1:3380/api/userlist
http://127.0.0.1:3380/api/userinfo
下图展示Postman测试接口:
https://i-blog.csdnimg.cn/direct/6ff7cd8b8d664dd988c4afe4c40b003f.jpeg#pic_center
3、项目目录截图

https://i-blog.csdnimg.cn/direct/04b86c5991974d07b8cbc85b4c60930f.jpeg#pic_center
六、全局见效的中间件

客户端发起的任何请求,到达服务器之后,都会触发中间件,叫做全局见效中间件。
通过app.use(中间件函数),即可定义一个全局见效的中间件,中间件本质上是一个function处理函数。
1、express内置的中间件

express.json() 解析JSON格式的请求体数据
express.urlencoded() 解析URL-encoded格式的请求体数据
app.js入口文件,所有路由之前注册这两个中间件:
// 处理post数据
app.use(express.json())
//处理xxx-www-urlencoded数据
app.use(express.urlencoded({ extended:false }))
2、解析token中间件(JWT相干)

1.JWT认证机制相干
什么是JWT:目前最流行的跨域认证解决方案。
JWT原理:用户的信息通过Token字符串的形式,保存在客户端浏览器中,服务器通过还原Token字符串的形式来认证用户的身份。
JWT组成三部门:Header(头部)、Payload(有效荷载)、Signature(署名)
JWT推荐利用方式:把JWT放在HTTP请求头的Authorization字段中,格式:Authorization:Bearer <token>
2.安装
jsonwebtoken 用于生成JWT字符串
express-jwt 用于将JWT字符串解析还原成JSON对象
//安装npm install
jsonwebtoken@8.5.1 express-jwt@5.3.3 3.配置中间件
根目录下新建config.js文件,代码如下:
module.exports = {
    jwtSecretKey:'pet_web_poppop No1.**', //密钥
    expiresIn:'10h' //token有效期
}
app.js文件中,路由之前配置中间件,代码如下:
// 导入 config.js 配置文件
const config = require('./config')
// 导入解析token中间件
const expressJWT = require('express-jwt')
//expressJWT({secret:config.jwtSecretKey}) 用来解析token的中间件
//unless({path:[/^\/api\//]}) 用来指定哪些接口不需要访问权限
app.use(expressJWT({secret:config.jwtSecretKey}).unless({path:[/^\/api\//]} ))
4.利用JWT (在登录乐成后生成JWT字符串)
调用 jsonwebtoken 包提供的 sign() 方法,将用户信息加密成JWT字符串,相应给客户端。
留意:千万不要把密码加密到token字符串中
代码如下:
// router/user.js
// 导入路由处理函数
const userRouterHandler = require('../router_handler/user')
// 登录
router.post('/login',userRouterHandler.userLoginHandle)

// /router_handler/user.js
// 导入jwt 相关包
const jwt = require('jsonwebtoken')
//登录处理函数
exports.userLoginHandle = (req,res)=>{
        let userinfo = req.body
    // 登录失败情况下的代码省略....
    // 用户登录成功后,生成JWT 字符串,通不过token属性响应给客户端
    res.send({
      status:200,
      message:'登录成功!',
      token:jwt.sign({username:userinfo.username},config.jwtSecretKey,{
            expiresIn:config.expiresIn
      })
    })
}
3、优化res.send()

res.send()方法用于发送相应数据给客户端,我们在app.js入口文件封装优化它,
必要留意:除了错误级别的中间件在所有路由之后配置 其他的中间件都要在路由之前配置。
// 应用级别的中间件(全局中间件)
app.use((req,res,next)=>{
    res.an = (err,status=1)=>{
      res.send({
            status,
            // 判断err是错误对象还是字符串
            message: err instanceof Error ? err.message : err
      })
    }
    next()
})
4、封装错误级别的中间件

错误级别的中间件作用:专门用来捕捉整个项目标异常错误,从而防止项目异常瓦解题目。我们在app.js入口文件封装它,留意:错误级别的中间件必须注册在所有路由之后!
//全局错误级别的中间件 捕获验证失败的错误
app.use((err,req,res,next)=>{
        //...
    if(err.name === 'UnauthorizedError') return res.an('身份认证失败!',401)
    // 未知错误
    res.an(err)
})
七、 配置cors跨域

1、安装

npm i cors@2.8.5
2、配置

app.js入口文件中注册 cors中间件为全局中间件
//导入中间件
const cors = require('cors')
//将cors 注册为全局中间件
app.use(cors())
八、优化表单数据验证

在实际开发中,前后端都必要对表单的数据进行合法性的验证,而且后端作为数据合法性验证的末了一个关口,在拦截非法数据方面,起到了至关重要的作用。利用第三方数据校验模块,来降低出错率,进步验证的效率与可维护性。
1、安装

//joi 定义验证规则npm install
joi// @escook/express-joi 实现主动对表单数据进行验证npm i @escook/express-joi 2、利用

新建 / validate/user.js 用户信息验证规则模块 并初始化代码如下:
//导入joi 验证规则
const joi = require('joi')

/**
* string() 值必须是字符串
* aiphanum() 值只能是包含a-zA-Z0-9的字符串
* min(length) 最小长度
* max(length)最大长度
* required() 值是必填项 不能为undefined
* pattern(正则表达式) 值必须符合正则表达式的规则
* **/

// 用户名验证规则
const username = joi.string().alphanum().min(1).max(10).required()
//密码验证规则
const password = joi.string().pattern(/^[\S]{6,12}$/).required()

// 注册和登录表单的验证规则对象
exports.reg_login_validate = {
    // 表示需要对 req.body 中的数据进行验证
    body:{
      username,
      password
    }
}
在/router/user.js 路由模块中进行验证,代码如下:
const expressJoi = require('@escook/express-joi')
const {reg_login_validate} = require('../validate/user')
// 登录
router.post('/login',expressJoi(reg_login_validate),userRouterHandler.userLoginHandle)
入口文件app.js中在全局错误级别的中间件配置捕捉验证失败的错误,代码如下:
// 导入验证规则
const joi = require('joi')
app.use((err,req,res,next)=>{
    // 验证表单数据,捕获失败错误
   if(err instanceof joi.ValidationError) return res.an(err)
    if(err.name === 'UnauthorizedError') return res.an('身份认证失败!',401)
    // 未知错误
    res.an(err)
})
九、 安装并配置mysql模块

1、安装

npm i mysql@2.18.1
2、配置

在项目根目录下新建 /db/index.js ,并初始化代码如下:
// 导入mysql模块
const mysql = require('mysql')

// 创建数据库连接对象
const db = mysql.createPool({
    host:'127.0.0.1', //数据库地址
    user:'root',   //数据库用户名
    password:'123456', //数据库密码
    database:'my_database' //数据库名称
})

// 向外共享 db 数据库连接对象
module.exports = db
3、利用示例

在用户路由处理函数模块中 router_handler/user.js 导入数据库毗连对象,获取数据库用户信息
// 导入数据库连接对象
const db = require('../db/index')
exports.getUserListHandle = (req,res)=>{
    // 定义查询用户的 sql 语句 首先确保你的数据库创建了user表
    const sql = 'select * from user where is_delete=0'
    db.query(sql,(err,results)=>{
      // 错误处理
      if(err) return res.an(err)
      // 查询成功处理
      res.send({
            status:200,
            message:'获取用户信息成功!',
            data:results
      })
    })
}
十、对密码进行加密处理bcryptjs

为了保证密码的安全性,不建议在数据库以明文的形式保存用户密码,下面介绍利用bcryptjs对密码进行加密处理。
1、安装

npm i bcryptjs@2.4.3
2、利用

在用户注册时对密码进行加密,再将信息保存到数据库中。
或者用户登录时检测输入的密码与数据库的密码是否同等。示例代码如下:
// router_hadler/user.js
//导入加密包 对密码加密
const bcrypt = require('bcryptjs')
//用户注册处理函数
exports.userRegisterHandle = (req,res)=>{
                  const userinfo = req.body
                // 此处省略注册逻辑代码...
                //使用bcryptjs对密码进行加密处理
                console.log('加密之前密码:',userinfo.password);
             userinfo.password = bcrypt.hashSync(userinfo.password,10)
             console.log('加密之后密码:',userinfo.password);
             //...
    })
}

//用户登录判断输入密码是否与数据中的密码一致
exports.userLoginHandle = (req,res)=>{
                //登录逻辑省略...
                const compareResults = bcrypt.compareSync(输入的密码数据,数据库密码数据)
      if(!compareResults) return res.cc('登录失败!')
      //...
    })
}
十一、利用svg-captcha和 cookie-parser生成图形验证码并保存到cookie中

svg-captcha 用于生成svg格式的验证码图片
cookie-parser 是express的一个中间件,用来实现对cookie的解析
1、 安装

npm install
cookie-parsernpm install
svg-captcha 2、注册 cookie-parser为全局中间件

app.js中代码:
// 导入包
const cookieParase = require('cookie-parser')
//注册
app.use(cookieParase())
// router/user.js
// 导入路由处理函数
const userRouterHandler = require('../router_handler/user')
//获取图形验证码
router.get('/getcode',userRouterHandler.getCode)

// /router_handler/user.js
//获取生成的图形验证码处理函数
exports.getCode = (req,res)=>{
    let captcha = svgCaptcha.create({
         // 翻转颜色
         inverse:false,
         // 字体大小
         fontSize:36,
         // 噪声线条数
         noise:2,
         // 宽度
         width:80,
         // 高度
         height:30,
   })
   // 保存到session 忽略大小
   req.session = captcha.text.toLowerCase()
   console.log(req.session);
   // 保存到cookie 方便前端调用验证
      res.cookie('captcha',req.session)
      res.setHeader('ContentType','image/svg+xml')
      res.write(String(captcha.data))
   res.end()
}
十二、multer解析表单数据(用于文件上传)

单文件上传 以及 多文件上传

用户路由模块中处理上传用户头像操作,代码如下:
// router/user.js
// 导入multer
const multer = require('multer')

// 设置存储引擎
const storage = multer.diskStorage({
        //文件存储路径
    destination: function (req, file, cb) {
            //保证项目中有此文件
      cb(null, './public/upload');
    },
    //存储的文件名处理
    filename: function (req, file, cb) {
      cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
    }
});
const upload = multer({ storage:storage})
// 导入路由处理函数
const userRouterHandler = require('../router_handler/user')
//,upload.single() 单文件上传
//上传用户头像user_pic 保存用户头像的字段
router.put('/updateuser',upload.single('user_pic').userRouterHandler.updateUserInfo)
//上传相册 upload.array(数据库相册的字段,限制上传大小)
router.put('/userpicture',upload.array('user_pics',12).userRouterHandler.updateUserPicture)

//router_handler/user.js 用户路由处理函数模块
//上传用户头像处理函数
exports.updateUserInfo = (req,res)=>{
        //req.file 上传的图片信息
        console.log(req.file)
        //处理图片操作...
}
//上传相册 处理函数
exports.updateUserPicture = (req,res)=>{
        //使用req.files接收 上传的图片信息
        console.log(req.files)
        //处理图片操作...
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: expres搭建一个基本的web网站服务器详细步调