likes
comments
collection
share

5分钟快速上手 Express

作者站长头像
站长
· 阅读数 34

前言

Express 官方表明,Express 是一个极简且灵活的 Node.js Web 应用框架,它为 Web 和移动应用提供了一组强大的功能,因此能够帮助我们快速的搭建 Web 服务器。

在 Express 出现之前,我们需要处理很多繁琐且没有技术含量的内容,例如:从获取路由 -> 解析路由 -> 分配路由 -> 处理路由等相关操作;我们需要自己手动去实现静态/动态资源的处理,例如:get 或者 post 参数的解析,cookie 的解析,日志的处理等相关操作。

Express 出现之后,就能帮助我们省去大量繁琐的环节, 让我们只用关注核心业务逻辑的开发,因为 Express 的相关插件已经帮我们集成,我们只需要按需引入插件即可。

创建项目

首先,创建一个项目文件夹,例如:文件名称叫做 express-template

然后,在项目根目录的终端命令行输入:npm init,初始化 package.json 项目文件。

5分钟快速上手 Express

其次,继续在终端命令行输入:npm install express 安装 express 包,接着创建 index.js 文件,在文件中增加如下内容:

// 1.导入express
const express = require('express')
// 2.调用 express 方法, 创建服务端实例对象
const app = express()

app.get('/', (req, res, next)=>{
    res.writeHead(200, {
        'Content-Type': 'text/plain; charset=utf-8;'
    })
    res.end('Hello Express!')
})

// 3.告诉服务端需要监听哪一个端口
app.listen(3000, ()=>{
    console.log('express 服务启动成功!')
})

最后,在命令行终端输入:node index.js,如果显示如下内容,则表示一个 Express 项目成功。

5分钟快速上手 Express

在浏览器中输入:http://localhost:3000 ,显示上述代码中返回的内容。

5分钟快速上手 Express

处理静态网页

在 Express 中处理静态网页需要使用 Express 提供的内置中间件函数 express.static,使用方式为在代码中增加如下代码:app.use(express.static(path.join(__dirname, 'public')))

// 1.导入express
const express = require('express')
const path = require('path')

// 2.调用express方法, 创建服务端实例对象
const app = express()

// 处理静态资源
app.use(express.static(path.join(__dirname, 'public')))

app.get('/', (req, res, next)=>{
    res.writeHead(200, {
        'Content-Type': 'text/plain; charset=utf-8;'
    });
    res.end('Hello Express!')
});

// 3.告诉服务端需要监听哪一个端口
app.listen(3000, ()=>{
    console.log('express 服务启动成功!')
})

处理动态网页

在 Express 中处理动态网页需要使用 Express 提供的 app.set(name, value) API 来告诉 express 动态资源存储在什么地方以及 express 动态网页使用的是什么模板引擎。此时我们可以在根目录下创建一个名称 views 的文件夹,同时在文件夹中创建 index.ejs 项目模板。

5分钟快速上手 Express

接着就是监听请求,返回渲染之后的动态网页,注意在 res.render 函数的第一个参数为 views 文件夹下的项目模板文件名称,第二个参数为传递的参数。

// 1.导入express
const express = require('express')
const path = require('path')

// 2.调用express方法, 创建服务端实例对象
const app = express()

// 处理静态资源
app.use(express.static(path.join(__dirname, 'public')))

// 处理动态资源
// 1.告诉 express 动态资源存储在什么地方
app.set('views', path.join(__dirname, 'views'))
// 2.告诉 express 动态网页使用的是什么模板引擎
app.set('view engine', 'ejs')
// 3.监听请求, 返回渲染之后的动态网页
app.get('/', (req, res, next)=>{
    // 注意点: express给请求对象和影响对象添加了很多自定义的方法
    res.render('index', {msg:'Hello Express!'})
})

// 3.告诉服务端需要监听哪一个端口
app.listen(3000, ()=>{
    console.log('express 服务启动成功!')
});

处理路由

在 Express 中处理路由需要使用 Express 提供的 app.get() API,这是通过 express 处理路由的一种方式。

值得注意的是,响应对象的json 方法是 express 给响应对象扩展的,这个方法会自动将对象转换成字符串之后返回,这个方法还会自动帮助我们设置响应头。

// 通过 express 处理路由
// 处理 get 请求
app.get('/api/blog/list', (req, res, next)=>{
    res.end('express nodes')
})
app.get('/api/user/login', (req, res, next)=>{
    res.json({
        name:'lisi',
        age:21,
        method: 'get'
    })
})
// 处理 post 请求
app.post('/api/blog/detail', (req, res, next)=>{
    res.end('Hello Express!')
})
app.post('/api/user/register', (req, res, next)=>{
    res.json({
        name:'lisi',
        age:21,
        method: 'post'
    })
})

另一种处理路由的方式为使用 Express 提供的 express.Router() 方法来处理路由:

首先,在项目根目录创建 router 文件夹。其次,在文件夹中创建 user.js 文件。

5分钟快速上手 Express

然后,在文件中增加如下代码,也就是上方示例图片中的代码:

const express = require('express')
const router = express.Router()
// 会将注册的地址和当前的地址拼接在一起来匹配
// /api/user/login
router.get('/login', (req, res, next) => {
  res.json({
    name: 'lisi',
    age: 21,
    method: 'get'
  })
})
router.post('/register', (req, res, next) => {
  res.json({
    name: 'lisi',
    age: 21,
    method: 'post'
  })
})
module.exports = router

最后,回到项目根目录中的 index.js 文件中,在此文件中增加如下代码:

// 引入 router 文件夹中定义的路由
const userRouter = require('./router/user')
// 通过 express 提供的 app.use() 的方式处理路由
app.use('/api/user', userRouter)

接着,在浏览器中访问 http://localhost:3000/api/user/login ,就会在浏览器中显示在 /router/user.js 中定义的关于 /loginget 请求的路由。

5分钟快速上手 Express

处理请求参数

在 Express 中处理请求参数需要使用 Express 提供的内置中间件函数 express.json() 以及 express.urlencoded()

其中 express.json([options]) 方法能够告诉 express 解析 application/json 类型的请求参数,

express.urlencoded([options]) 方法能够告诉 express 解析表单类型的请求参数。

最后,express 会将解析之后的内容转换成对象的 post 请求参数放到请求对象的 body 属性中。

app.get('/get', (req, res, next)=>{
    // express 会将 get 的请求参数转换成对象之后,放到请求对象的 query 属性中
    console.log(req.query)
})
app.use(express.json()) // 告诉 express 能够解析 application/json 类型的请求参数
app.use(express.urlencoded({extended: false})) // 告诉 express 能够解析表单类型的请求参数 application/x-www-form-urlencoded
// express 会将解析之后的内容转换成对象的 post 请求参数放到请求对象的 body 属性中
app.post('/post', (req, res, next)=>{
    console.log(req.body)
})

处理 Cookies

在 Express 中处理 Cookies 需要使用 Express 提供的 res.cookie() API,同时还要使用 cookie-parser 这个第三方插件。

const cookieParser = require('cookie-parser')
// 处理cookie
app.get('/setCookie', (req, res, next)=>{
    res.cookie('username', 'lisi', {httpOnly: true, path: '/', maxAge: 10000})
    res.end()
})
app.use(cookieParser())
app.get('/getCookie', (req, res, next)=>{
    console.log(req.cookies)
})

正确处理 next

在 Express 中,app.use() 既可以处理没有路由地址的请求,也可以处理有路由地址请求,同样既可以处理 get 请求,也可以处理 post 请求。

值得注意的是,在处理请求的时候都是从上至下依次判断的,谁满足条件,就先处理谁。如果在处理请求的回调函数中没有调用 next 方法,那么处理完之后就不会再继续往下判断,反之,如果调用 next 方法,处理完之后还是会继续往下判断的。

补充知识点:app.get() 专门用于处理 GET 请求,而 app.use() 可以处理任何类型的请求,实际上 app.use() 是一个更通用的中间件挂载方法,也可用于挂载路由处理器。

例如,在 index.js增加如下代码,注意把处理路由的方式一注释掉,两种方式不能同时存在。

// next 的使用方式
app.use((req, res, next) => {
  console.log('use1 没有路由地址')
  next()
})
app.use('/', (req, res, next) => {
  console.log('use2 有路由地址')
  next()
})
app.get('/api', (req, res, next) => {
  console.log('get /api')
  next()
})
app.get('/api/user', (req, res, next) => {
  console.log('get /api/user')
  next()
})

在项目终端命令行输入:node index.js,然后在浏览器中访问 http://localhost:3000/api/user ,接着就会在终端命令行显示如下内容:

5分钟快速上手 Express

这说明,默认情况下 express 会从上至下的匹配路由处理,一旦匹配到就会执行,执行完毕之后如果没有调用 next 就停止,如果调用 next 就继续向下匹配。值得研究的是,我们可以将同一个请求的多个业务逻辑拆分到不同的方法中去处理,这样可以提升代码的可读性和可维护性, 以及保证代码的单一性。

因此,next 的正确打开方式为如下代码:

app.get(
  '/api/user',
  (req, res, next) => {
    console.log('验证用户是否登陆')
    next()
  },
  (req, res, next) => {
    console.log('用户已经登陆, 可以查看用户信息')
  }
)

处理错误

由于在处理请求的时候会从上至下的匹配,所以只要前面的路由都没有匹配到,就会执行下面的 use,正确处理错误的方式为在项目中增加如下代码:

// 引入 http-errors 第三方包,用于处理错误
const createError = require('http-errors')
app.use((req, res, next) => {
  next(createError(404))
})
app.use((err, req, res, next) => {
  console.log(err.status, err.message)
  res.end(err.message)
})

接着,在命令行终端输入:node index.js 启动项目。

然后,在浏览器中访问一个不存在的路由:http://localhost:3000/api/user/123 ,命令行终端就会显示打印的错误信息:

5分钟快速上手 Express

同样在浏览器也会显示出 http-errors 这个第三包返回至浏览器中的错误信息:

5分钟快速上手 Express

总结

Express 最早的版本是在2010年发布的,目前 Express 最新的版本4.19.2,而最新的 beta 版本5.0.0-beta.3,这意味着 Express 团队在一直持续维护着 Express,并且 Express 5.0 的版本不久也会正式发布。

虽然 Express 是一个古老的框架,但是它并没有过时。这是因为公司老项目仍然在使用,并且 Koa 就是由 Express 原班人马打造的。况且国内的企业级 Node.js 框架 Egg.js 就是由 Koa 打造的。

因此我们学会 Express 能够更快的学习 Koa 和 Egg.js,甚至是 Nest.js

转载自:https://juejin.cn/post/7365119428840570943
评论
请登录