NodeJs 第十一章 express

Express 是基于 Node.js 平台,快速、开放、极简的 web 开发框架

基本使用

安装

npm install express --save

示例代码

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

Express 官方推荐脚手架

通过应用生成器工具 express-generator 可以快速创建一个应用的骨架。

你可以通过 npx (包含在 Node.js 8.2.0 及更高版本中)命令来运行 Express 应用程序生成器。

npx express-generator

命令行参数

 	-h, --help          输出使用方法
        --version       输出版本号
    -e, --ejs           添加对 ejs 模板引擎的支持
        --hbs           添加对 handlebars 模板引擎的支持
        --pug           添加对 pug 模板引擎的支持
    -H, --hogan         添加对 hogan.js 模板引擎的支持
        --no-view       创建不带视图引擎的项目
    -v, --view <engine> 添加对视图引擎(view) <engine> 的支持 (ejs|hbs|hjs|jade|pug|twig|vash) (默认是 jade 模板引擎)
    -c, --css <engine>  添加样式表引擎 <engine> 的支持 (less|stylus|compass|sass) (默认是普通的 css 文件)
        --git           添加 .gitignore
    -f, --force         强制在非空目录下创建

启动应用

  • 在 MacOS 或 Linux 中
DEBUG=myapp:* npm start
  • Windows 命令行中
set DEBUG=myapp:* & npm start
  • Windows 的 PowerShell 中
$env:DEBUG='myapp:*'; npm start

然后在浏览器中打开 http://localhost:3000/ 网址就可以看到这个应用了。

如何利用 Express 托管静态文件

express.static 内置中间件函数可以为我们提供 图像、CSS 文件和 JavaScript 文件之类的静态文件托管

express.static(root, [options])

多个静态资源目录,请多次调用 express.static 中间件函数:

app.use(express.static('public'))
app.use(express.static('files'))

路由

路由指的是确定应用程序如何响应对特定端点的客户机请求,这是一个URI(或路径)和一个特定的HTTP请求方法(GET、POST等)。

每个路由都可以有一个或多个handler函数,这些函数在匹配路由时执行。

路由定义采用以下结构

app.METHOD(PATH, HANDLER)
  • app: express的一个实例。
  • METHOD:
    • HTTP请求方法,小写(支持所有的http请求方法,特殊请求方法 all , 用于在所有HTTP请求方法的路径上加载中间件函数)。
  • PATH:
    • 路由路径,可以是字符串、字符串模式或正则表达式。
    • 如果需要在路径字符串中使用美元字符( ) ,请将其转义后用 ( [ a n d ] ) 括起来。例如 , / d a t a / ),请将其转义后用([and])括起来。例如, /data/ ),请将其转义后用([and])括起来。例如,/data/book 请求的路径字符串将是 /data/([\$])book
  • HANDLER:
    • 匹配路由时执行的函数。
    • 可以提供多个行为类似中间件的回调函数来处理请求。唯一的例外是,这些回调可能会调用next(‘route’)来绕过剩余的路由回调。您可以使用这种机制在路由上施加前置条件,然后在没有理由继续当前路由时将控制权传递给后续路由。
app.get('/example/b', (req, res, next) => {
  console.log('the response will be sent by the next function ...')
  next()
}, (req, res) => {
  res.send('Hello from B!')
})

app.route

app.route() 为路由路径创建可链接的路由处理程序。由于路径是在单个位置指定的,因此创建模块化路由很有帮助,还可以减少冗余和错别字。

下面是一个用app.route()定义的链式路由处理程序的例子。

app.route('/book')
  .get((req, res) => {
    res.send('Get a random book')
  })
  .post((req, res) => {
    res.send('Add a book')
  })
  .put((req, res) => {
    res.send('Update the book')
  })

express.Router

express.Route 可以将路由器创建为一个模块,在其中加载一个中间件函数,定义一些路由,并将路由器模块挂载到主应用的某个路径上

const express = require('express')
const router = express.Router()
const app = express()

// middleware that is specific to this router
router.use((req, res, next) => {
  console.log('Time: ', Date.now())
  next()
})
// define the home page route
router.get('/', (req, res) => {
  res.send('Birds home page')
})
// define the about route
router.get('/about', (req, res) => {
  res.send('About birds')
})

app.use('/pub', router)

中间件

中间件是可以访问请求对象( req)、响应对象( res) 以及next应用程序请求-响应周期中的函数。该next函数是 Express 路由器中的一个函数,当被调用时,它会执行当前中间件之后的中间件。

如果当前的中间件函数没有结束请求,则必须调用next()将控制权传递给下一个中间件函数。否则,请求将被挂起。

中间件加载的顺序很重要:首先加载的中间件函数也首先执行

在这里插入图片描述
如何使用中间件

  • 应用层
const express = require('express')
const app = express()

app.use((req, res, next) => {
  console.log('Time:', Date.now())
  next()
})
  • 路由层
const express = require('express')
const app = express()
const router = express.Router()

// a middleware function with no mount path. This code is executed for every request to the router
router.use((req, res, next) => {
  console.log('Time:', Date.now())
  next()
})
  • 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})
  • 内置中间件

    • express.static提供静态资源,例如 HTML 文件、图像等。
    • express.json使用 JSON 有效负载解析传入请求。注意:适用于 Express 4.16.0+
    • express.urlencoded使用 URL 编码的有效负载解析传入请求。注意:适用于 Express 4.16.0+

如何覆盖 Express API

Express API 由请求和响应对象的各种方法和属性组成。这些都是通过原型继承的。Express API 有两个扩展点:

  1. 全局原型位于 express.requestexpress.response
  2. 特定原型位于 app.requestapp.response

覆盖方法

app.response.sendStatus = function (statusCode, type, message) {
  // code is intentionally kept simple for demonstration purpose
  return this.contentType(type)
    .status(statusCode)
    .send(message)
}

覆盖属性

Object.defineProperty(app.request, 'ip', {
  configurable: true,
  enumerable: true,
  get () { return this.get('Client-IP') }
})
  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值