当向NodeJs服务端发送POST请求时,发现拿到的request.body
为空对象,发现请求的参数都没问题,但就是拿不到数据,这是为什么呢?让我们来一探究竟。
原因
浏览器在发起POST请求时,我们一般会指定头部:Content-Type
,最常见的就是application/json
,代表传输的是json数据,对应的,我们在NodeJs服务端需要去解析这些数据。
body-parser
解析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
返回一个仅处理字符串格式处理的中间件。这个方法支持gzip
和deflate
编码的数据压缩。解析后,其后的所有的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
发出请求带有typeContent-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
,并且在服务端加上了body-parser
的解析,我们就可以拿到正确的数据了。
评论 (0)