Express API 总结

614 阅读6分钟

Express 是一个 Node.js Web 框架。 其 API 共有 5 类,分别是:

  1. express()
  2. Application
  3. Request
  4. Response
  5. Router

以上 5 类 API 的使用,文中通过创建 express-demo 来熟悉。

在 express-demo 下运行 yarn init -y 创建默认的 package.json,运行 yarn add express 安装 express;创建 app.js,添加以下代码:

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

app.use((req, res, next) => {
  res.send('hi')
})

app.listen(5001, () => {
  console.log('listen 5001')
})

创建了 express 服务,监听 5001 端口,运行 node app.js 即可启动服务,在浏览器输入 http://localhost:5001/ 可以看到如下: image.png

看到 hi 说明运行正常。以下示例均由 postman 构造请求。

express()


用于内置中间件。express() 创建了一个 Express 应用,即 demo 中的 app。

共 7 个 API,此处介绍 3 个常用的 API

  1. express.json()
  2. express.static()
  3. express.Router()

express.json()

假如请求体即 req.body 是 json,会将完整的 json 解析出来,返回解析 json 的中间件。

下面示例是未添加 express.json() 的代码:

app.use((req, res, next) => {
  console.log('req.body')
  console.log(req.body)
  res.send('hi')
  next()
})

请求如下: image.png

终端打印如下:

image.png

可以看到没添加时打印结果是 undefined。当添加 express.json() 时,代码如下:

app.use(express.json())

app.use((req, res, next) => {
  console.log('req.body')
  console.log(req.body)
  res.send('hi')
  next()
})

再次进行相同的请求,终端打印结果如下:

image.png

express.static(root)

Express 使用 express.static 中间件函数设置静态目录的顺序来查找文件。将包含静态资源文件的目录传递给 express.static 中间件函数,以便开始直接提供这些文件。express.static 默认做一个静态服务器,参数 root 是放置静态资源的根目录,只要访问路径在 root 目录下,就会在 root 目录下查找,没有则在外面查找。

根目录下创建 yyy 目录,在 yyy 中创建 index.html。以 root 为 'yyy' 为例,代码如下:

app.use(express.static('yyy'))

app.use((req, res, next) => {
  res.send('hi')
})

要访问 yyy/index.html 只要在浏览器地址栏输入 http://localhost:5001/index.html 即可,由于 http://localhost:5001/ 默认就是 http://localhost:5001/index.html ,得到请求如下:

image.png 已不再是原来的 hi,如果请求的是 http://localhost:5001/xxx 则结果如下:

image.png

如需使用多个静态目录文件,则需多次调用 express.static 中间件函数。

如果要为静态资源文件创建虚拟路径前缀,可以在 app.use 中指定,假设可以通过访问 http://localhost:5001/static/index.html 得到 yyy/index.html,代码如下:

app.use('/static', express.static('yyy'))

请求如下: image.png

express.Router()

用于创建 router 对象,与 Router API 配合使用,具体使用见 Router API 部分。

Application


用于应用设置,如模板配置、中间件、挂载路由。也就是本文例子中的 app(主应用)。

共 22 个 API,此处介绍 3 个常用的 API

  1. app.set()
  2. app.METHOD()
  3. app.use()

app.set()

app.set(name, value) 将 value 赋值给 name 用于存储数据,可以通过 app.get(name) 获得值;也有一些指定的 name,比如 case sensitive routing(大小写敏感) 、views(模板文件所在目录)、view engine(视图引擎模板)等。

以是否区分路由大小写为例,代码如下:

app.set('case sensitive routing', true) // 区分路由大小写

app.get('/style.css', (req, res, next) => {
  res.send('style.css')
})
app.get('/STYLE.css', (req, res, next) => {
  res.send('STYLE.css')
})

请求如下: image.png image.png 可以看到 /style.css 和 /STYLE.css 得到的结果是不一样的,说明设置生效。 也可以用 app.set 来配置模板,通常与 app.render 配合使用,此文不展开详情介绍介绍,可参考官网指南使用模板引擎

app.METHOD()

也就是 app.get / app.post / app.delete / app.put 等请求,比如 get 用法 app.get(path, callback),参数分别是路径和该路径下执行的回调。

例如在 /test 路径下的 get/post/delete/patch 方法请求,代码如下:

app.get('/test', (req, res, next) => {
  res.send('get /test')
})
app.post('/test', (req, res, next) => {
  res.send('post /test')
})
app.delete('/test', (req, res, next) => {
  res.send('delete /test')
})
app.patch('/test', (req, res, next) => {
  res.send('patch /test')
})

请求如下: image.png image.png image.png image.png

app.use()

用于挂载中间件,或执行指定路径下的方法。例如,上面代码可以写成如下代码:

app.use('/test', (req, res, next) => {
  if(req.method === 'GET'){
    res.send('get /test')
  }
  if(req.method === 'POST'){
    res.send('post /test')
  }
  if(req.method === 'DELETE'){
    res.send('delete /test')
  }
  if(req.method === 'PATCH'){
    res.send('patch /test')
  }
  next()
})

请求得到的结果与 app.get / app.post / app.delete / app.patch 一致, 相当于 app.use 的简写方式,不同之处在于 app.use 可用于任何方法,而不指定某种具体的请求方法。当不指定路径时,app.use 可用于任意的请求和路径,好比请求是 /xxx 时,得到的响应时 hi,如下: image.png

Request


用于操作请求。app.use((req, res, next) => {}) 中的 req 就代表 http 请求。

共 28 个 API,此处介绍 2 个常用的 API

  1. req.get()
  2. req.param()

req.get()

返回请求头的字段,比如 req.get('Content-Type'),代码如下:

app.use((req, res, next) => {
  console.log(req.get('Content-Type'))
  res.send('hi')
})

请求如下: image.png 终端打印如下:

image.png

req.param()

req.param(name) 返回 req.params | req.body | req.query 中的 name 值。从 Express 4.11 起开始使用 req.paramsreq.bodyreq.query 代替 req.param。

app.use('/:name', (req, res, next) => {
  console.log(req.params)
  console.log(req.body)
  console.log(req.query)
  console.log(req.param('name'))
  res.send('hi')
})

请求如下: image.png 终端打印如下:

image.png

Response


用于操作响应。app.use((req, res, next) => {}) 中的 res 就代表 http 响应。

共 24 个 API,此处介绍 3 个常用的 API

  1. res.send()
  2. res.status()
  3. res.format()

res.send()

发送响应体,内容可以是 Buffer、String、Boolean、Array。res.send 是非流式操作,一次发完所有内容,与此同时还会自动设置 header。

代码如下:

app.use((req, res, next) => {
  res.send('<p>p标签</p>')
})

请求如下: image.png 响应头: image.png

res.status()

设置响应状态码,可以链式调用。

比如返回404,代码如下:

app.use((req, res, next) => {
  res.status(404).send('404 not found')
})

请求如下: image.png

res.format()

根据请求头中的 Accept 类型返回相应的内容。

代码如下:

app.get('/test', (req, res, next) => {
  res.format({
    'text/plain': function () {
      res.send('hey')
    },
  
    'text/html': function () {
      res.send('<p>hey</p>')
    },
  
    'application/json': function () {
      res.send({ message: 'hey' })
    },
  
    default: function () {
      res.status(406).send('Not Acceptable')
    }
  })
})

请求如下:

  • 设置请求头 Accept 为 text/plain image.png
  • 设置请求头 Accept 为 text/html image.png
  • 设置请求头 Accept 为 application/json image.png
  • 设置请求头 Accept 为 application/xml,不属于代码中的任一类型,故发送默认内容 image.png

Router


用于操作路由。可以被认为是一个 mini app,挂载到 app,前面提到 Router 常跟 express.Router() 一起配合使用。

比如有一个 /user 路径是列出所有用户的页面,/user/:id 是根据 id 找出的某个具体的用户信息,/user/:id/edit 是根据 id 编辑某个具体的用户信息,代码可以如下:

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

app.get('/user/:id', (req, res, next) => {
  res.send('/user/:id')
})

app.get('/user/:id/edit', (req, res, next) => {
  res.send('/user/:id/edit')
})

这样写无疑是有点重复的,都是 /user 路径下的路由,那么我们可以把这些子路径都挂载到 /user 下即可,app.js 中跟 /user 路由有关的代码改写成:

// app.js
app.use('/user', userRouter)

根目录下创建 routes 文件夹,在 routes 下添加 user.js 用于放置跟 /user 有关的路由,代码如下:

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

router.get('/', (req, res, next) => {
  res.send('/user')
})

router.get('/:id', (req, res, next) => {
  res.send('/user/:id')
})

router.get('/:id/edit', (req, res, next) => {
  res.send('/user/:id/edit')
})

module.exports = router

同时将导出的 router 导入到 app.js 中,代码如下:

const userRouter = require('./routes/user')

请求如下: image.png image.png image.png 可以看出 /user,/user/1,/user/1/eidt 得到的返回都不相同。从而得知,可以把不同根路径下的路由分成几个不同的部分挂载到 app 下,方便书写和维护。

以上就是此文的全部内容,有问题欢迎指出,谢谢阅读~