前面我们已经学习了使用http内置模块来搭建Web服务器,为什么还要使用框架?
目前在Node中比较流行的Web服务器框架是express、koa:
express早于koa出现,并且在Node社区中迅速流行起来:
express的使用过程有两种方式:
方式一:安装express-generator
安装脚手架
npm install -g express-generator
创建项目
express express-demo
安装依赖
npm install
启动项目
node bin/www
方式二:从零搭建自己的express应用结构;
npm init -y
我们来创建第一个express项目:
请求的路径中如果有一些参数,可以这样表达:
返回数据,我们可以方便的使用json:
Express是一个路由和中间件的Web框架,它本身的功能非常少:
中间件是什么呢?
中间件中可以执行哪些任务呢?
如果当前中间件功能没有结束请求-响应周期,则必须调用next()将控制权传递给下一个中间件功能,否则,请求
将被挂起。
那么,如何将一个中间件应用到我们的应用程序中呢?
我们先来学习use的用法,因为methods的方式本质是use的特殊情况;
并非所有的中间件都需要我们从零去编写:
但是,事实上我们可以使用expres内置的中间件或者使用body-parser来完成:
如果我们解析的是 application/x-www-form-urlencoded:
extended属性:
true:那么对urlencoded进行解析时,它使用的是第三方库:qs
/false:那么对urlencoded进行解析时,它使用的是Node内置模快:querystring
const express = require('express')
const app = express()
// 编写处理json解析的中间件
app.use((req, res, next) => {
if (req.headers["content-type"] === "application/json") {
req.on('data', (data) => {
const info = JSON.parse(data.toString())
req.body = info
})
req.on('end', () => {
next()
})
} else {
next()
}
})
//body-porser:express3.x内置express框架
//body-parser:express4.x被分离出去
//body-parser类似功能;express4,16.x内置成函数
// app.use(express.json())
app.post('/login', (req, res, next) => {
// req.on('data', (data) => {
// console.log(data.toString())
// })
// req.on('end', () => {
// res.end('zep, Welcome Back~')
// })
console.log(req.body)
res.end('zep, Welcome Back~')
})
app.post('/product', (req, res, next) => {
req.on('data', (data) => {
console.log(data.toString())
})
req.on('end', () => {
res.end('Upload Product Info Success')
})
})
app.listen(8000, () => {
console.log('express服务器启动成功')
})
如果我们希望借助于multer帮助我们解析一些form-data中的普通数据,那么我们可以使用any:
注意: 这里不要把upload.any()作为全局中间件,否则会与后面文件上传功能冲突!!!
正确做法:
https://github.com/expressjs/multer
上传文件,我们可以使用express提供的multer来完成:
const express = require('express')
const multer = require('multer')
const path = require('path')
const app = express()
app.use(express.json())
app.use(express.urlencoded({extended: true}))
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './uploads/')
},
filename: (req, file, cb) => {
// console.log(file)
cb(null, Date.now() + path.extname(file.originalname))
}
})
const upload = multer({
// dest: './uploads/'
storage
})
app.post('/upload', upload.single('file'), (req, res, next) => {
console.log(req.files)
res.end('文件上传成功~')
})
app.post('/login', upload.any(), (req, res, next) => {
console.log(req.body)
res.end('登录成功')
})
app.listen(8000, () => {
console.log('express服务器启动成功')
})
https://github.com/expressjs/morgan
如果我们希望将请求日志记录下来,那么可以使用express官网开发的第三方库:morgan
客户端传递到服务器参数的方法常见的是5种:
目前我们主要有两种方式没有讲,下面我进行一个演练。
如果我们将所有的代码逻辑都写在app中,那么app会变得越来越复杂:
我们可以使用 express.Router来创建一个路由处理程序:
部署静态资源我们可以选择很多方式:
const express = require('express')
const userRouter = require('./routers/user.js')
const app = express()
const USERNAME_DOES_NOT_EXISTS = 'USERNAME_DOES_NOT_EXISTS'
const USERNAME_ALREADY_EXISTS = 'USERNAME_ALREADY_EXISTS'
app.use('/users', userRouter)
app.post('/login', (req, res, next) => {
const isLogin = false
if (isLogin) {
res.json('user login success~')
} else {
// res.type(400)
// res.json('username does not exists')
next(new Error(USERNAME_DOES_NOT_EXISTS))
}
})
app.post('/register', (req, res, next) => {
const isExists = true
if (!isExists) {
res.json('user register success~')
} else {
// res.type(400)
// res.json('username already exists')
next(new Error(USERNAME_ALREADY_EXISTS))
}
})
app.use((err, req, res, next) => {
let status = 400
let message = ''
switch (err.message) {
case USERNAME_DOES_NOT_EXISTS:
message = 'username does not exists~'
break
case USERNAME_ALREADY_EXISTS:
message = 'username already exists~'
break
default:
message = 'NOT FOUND'
}
res.status(status)
res.json({
errCode: status,
errMessage: message
})
})
app.listen(8000, () => {
console.log('路由服务器启动成功~')
})