NodeJs服务端POST请求拿不到body的内容?

233次阅读
没有评论

共计 3248 个字符,预计需要花费 9 分钟才能阅读完成。

在开发中我们会遇到这样的问题:前端使用 ajax 正常发起 POST 请求,把数据都塞在 body 里,然后在使用 NodeJs 做服务端接受请求时,发现拿不到 `request.body` 的内容,这是怎么回事呢?

浏览器在发起 POST 请求时,我们一般会指定头部:Content-Type,最常见的就是application/json,代表传输的是 json 数据,对应的,我们在 NodeJs 服务端需要去解析这些数据。

解析 body 最常用的库是body-parser,它支持对多种类型进行解析:

解析 JSON

发出请求需要带上Content-Type:application/json

服务端设置:

app.use(bodyParser.json(options)) 

options是一个包含以下可选值的对象

  • inflate – 设置为 true 时,deflate 压缩数据会被解压缩;设置为 true 时,deflate 压缩数据会被拒绝。默认为 true。
  • limit – 设置请求的最大数据量。默认为 ’100kb’
  • reviver – 传递给 JSON.parse()方法的第二个参数,详见JSON.parse()
  • strict – 设置为 true 时,仅会解析 Array 和 Object 两种格式;设置为 false 会解析所有 JSON.parse 支持的格式。默认为 true
  • type – 该选项用于设置为指定 MIME 类型的数据使用当前解析中间件。这个选项可以是一个函数或是字符串,当是字符串是会使用 type-is 来查找 MIMI 类型;当为函数时,中间件会通过 fn(req)来获取实际值。默认为application/json
  • verify – 这个选项仅在 verify(req, res, buf, encoding)时受支持

解析二进制

发出请求可以带上自定义 type,方便服务端处理,例如Content-Type:application/x-gzip

服务端设置:

app.use(bodyParser.raw(options)) 

bodyParser.raw返回一个仅处理字符串格式处理的中间件。这个方法支持 gzipdeflate编码的数据压缩。解析后,其后的所有的 req.body 中将会是一个字符串值。

options是一个包含以下可选值的对象

  • defaultCharset – 如果 Content-Type 后没有指定编码时,使用此编码。默认为 ’utf-8′
  • inflate – 设置为 true 时,deflate 压缩数据会被解压缩;设置为 true 时,deflate 压缩数据会被拒绝。默认为 true。
  • limit – 设置请求的最大数据量。默认为 ’100kb’
  • type – 该选项用于设置为指定 MIME 类型的数据使用当前解析中间件。这个选项可以是一个函数或是字符串,当是字符串是会使用 type-is 来查找 MIMI 类型;当为函数是,中间件会通过 fn(req)来获取实际值。默认为application/octet-stream。也就是说这里可以指定我们自定义的一些Content-Type,来告诉服务端需要对哪些请求进行解析。
  • verify – 这个选项仅在 verify(req, res, buf, encoding)时受支持

解析文本

发出请求带有 typeContent-Type:text/plain

服务端设置:

app.use(bodyParser.text(options)) 

将所有的实体解析为字符串,只查看内容类型头与类型选项匹配的请求。该解析器支持 gzip 的自动解压缩和压缩编码。

在中间件 (即 req.body) 之后,在请求对象上填充包含解析数据的新体字符串。这将是一个主体的字符串。

options是一个包含以下可选值的对象

  • defaultCharset – 如果 Content-Type 在请求的标题中未指定字符集,请指定文本内容的缺省字符集。默认为 utf-8。
  • inflate – 设置为 true 时,deflate 压缩数据会被解压缩;设置为 true 时,deflate 压缩数据会被拒绝。默认为 true。
  • limit – 控制最大请求主体大小。如果这是一个数字,则该值指定字节数; 如果它是一个字符串,则将该值传递给 字节库进行解析。默认为’100kb’。
  • type – 该 type 选项用于确定中间件将解析的 MIME 类型。该选项可以是字符串,字符串数组或函数。如果不是函数,则 type 选项直接传递到 类型库,这可以是扩展名(like txt),MIME 类型(like text/pl ain)或带有通配符(如 /or text/*)的 MIME 类型。如果一个函数,这个 type 选项被调用,fn(req)并且如果返回一个真值,那么请求被解析。默认为 text/plain。
  • verify – 该 verify 选项(如果提供)被称为 verify(req, res, buf,encoding),其中 buf 是 Buffer 原始请求主体,并且 encoding 是请求的编码。抛出错误可以中止解析。

特别说明
使用 navigation.sendBeacon 发出请求时,默认传的Content-Type:text/plain, 所以解析该类请求需要用bodyParser.text()

解析 urlencode

发出请求带有 type:Content-Type:application/x-www-form-urlencoded

服务端设置:

app.use(bodyParser.urlencoded(options)) 

返回仅解析 urlencoded 正文的中间件,只查看 Content-Type 头部与 type 选项匹配的请求。此解析器只接受身体的 UTF- 8 编码,并支持自动 gzip 和 deflate 编码。

body 包含解析数据的新对象 request 在中间件(iereq.body)之后被填充在对象上。该对象将包含键 - 值对,其中该值可以是一个字符串或阵列(时 extended 是 false),或任何类型的(当 extended 是 true)。

options是一个包含以下可选值的对象

  • extended – 该 extended 选项允许选择是将 URL 编码的数据与 querystring 库(当值为 false)或 qs 库(当值为 true)解析。“extended”语法允许将丰富的对象和数组编码为 URL 编码的格式,从而允许使用 URL 编码的类似 JSON 的体验。有关更多信息,请 参阅qs 库
  • limit – 设置为 true 时,deflate 压缩数据会被解压缩;设置为 true 时,deflate 压缩数据会被拒绝。默认为 true。limit 控制最大请求主体大小。如果这是一个数字,则该值指定字节数; 如果它是一个字符串,则将该值传递给 字节库进行解析。默认为’100kb’。
  • parameterLimit – 该 parameterLimit 选项控制 URL 编码数据中允许的最大参数数量。如果一个请求包含比这个值更多的参数,一个 413 将被返回给客户端。默认为 1000。
  • type – 该 type 选项用于确定中间件将解析的 MIME 类型。该选项可以是字符串,字符串数组或函数。如果不是函数,则 type 选项直接传递到类型库,这可以是扩展名(例如 urlencoded),MIME 类型(例如 application/x-www-form-urlencoded)或带有通配符(如 */x-www-form-urlencoded)的 MIME 类型。如果一个函数,这个 type 选项被调用,fn(req)并且如果返回一个真值,那么请求被解析。默认为application/x-www-form-urlencoded
  • verify – 该 verify 选项(如果提供)被称为 verify(req,res,buf,encoding),其中 buf 是 Buffer 原始请求主体,并且 encoding 是请求的编码。抛出错误可以中止解析。

总结

在实际开发过程中,我们需要知道浏览器或者说客户端请求的头部:Content-Type 是什么,然后在服务端根据对应的 type 去进行数据解析,这样才能正确拿到数据。

正文完
 
西蒙
版权声明:本站原创文章,由 西蒙 2023-09-19发表,共计3248字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码