这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战
Express 不会自动为您解析 HTTP 请求正文,但它有一个官方支持的中间件包 body-parser,用于解析 HTTP 请求正文。从 v4.16.0 开始,Express 自带一个内置的 JSON 请求正文解析中间件,对于大多数 JavaScript 应用程序来说已经足够好了。
JSON 请求体
Express 有一个内置 express.json() 方法,该方法返回一个 Express 中间件函数,将 JSON HTTP 请求体解析为 JavaScript 对象。
json() 中间件将一个 body 属性添加到 Express req 中。您可以使用 req.body 访问已解析的请求体,如下所示:
const axios = require('axios')
const express = require('express')
const app = express()
// 解析此应用程序的 JSON 正文。确保在路由处理程序之前放置 app.use(express.json())!
app.use(express.json())
app.post('*', (req, res) => {
console.log(req.body) // 包含解析 JSON 的 JavaScript 对象
res.json(req.body)
})
await app.listen(5000)
const res = await axios.post('http://localhost:5000/', {
answer: 42
})
console.log(res.data) // { answer: 42 }
常见问题
如果 JSON 正文格式不正确,Express 将错误输出 HTTP 400。此错误还会触发错误处理中间件。
const axios = require('axios')
const express = require('express')
const app = express()
app.use(express.json())
app.post('*', (req, res) => {
res.json(req.body)
})
// 添加错误处理中间件,Express 将在 JSON 格式错误时调用该中间件。
app.use(function(err, req, res, next) {
console.log(err.message) // 'SyntaxError: Unexpected token n in JSON at position 0'
next(err)
})
await app.listen(5000)
const headers = { 'Content-Type': 'application/json' }
const err = await axios
.post('http://localhost:5000/', 'not json', { headers })
.then(() => null, err => err)
// 如果 JSON 中间件解析失败,Express 将默认发送 HTTP 400。
console.log(err.response.status) // 400
console.log(err.message) // 'Request failed with status code 400'
需要注意的是,默认情况下,json() 中间件会忽略 Content-Type 标头不是 Express 识别为 JSON 的任何请求。如果 express.json() 正在默默地忽略您的请求,请确保检查 Content-Type 标头。
const axios = require('axios')
const express = require('express')
const app = express()
app.use(express.json())
app.post('*', (req, res) => {
// undefined。body 解析器由于内容类型标头而忽略此请求
console.log(req.body)
console.log(res.json(req.body))
})
await app.listen(5000)
const headers = { 'Content-Type': 'text/plain' }
const res = await axios
.post('http://localhost:5000/', 'not json', { headers })
console.log(res.data) // 为空对象 {}
URL 编码的表单正文解析器
Express 有一个官方支持的模块 body-parser,它包括一个 解析器,用于 URL 编码的请求体,比如 HTML 表单提交的请求体。
const axios = require('axios')
const express = require('express')
const app = express()
app.use(require('body-parser').urlencoded({ extended: false }))
app.post('*', (req, res) => {
console.log(req.body) // { answer: 42 }
console.log(res.json(req.body))
})
await app.listen(5000)
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
const res = await axios
.post('http://localhost:5000/', 'answer=42', { headers })
console.log(res.data) // { answer: 42 }