Node的http模块只对Http报文的头部进行解析,然后出发request事件。如果请求中还携带内容,就需要我们自行解析,那么如何解析呢?这节就说这个~
判断是否有上传内容
通过报文头的transfer-encoding和content-length的判断,我们来确定请求是否包含了其他内容
const hasBody = (req) => {
return 'transfer-encoding' in req.headers || 'content-length' in req.headers;
}
解析数据
解析报文数据之后,会通过data事件进行监听,因此我们可以通过流的方式处理即可
const handleBody = (req,res) => {
console.log(req.method,'kk')
if ( hasBody(req) ) {
const buffers = [];
let size = 0;
req.on('data',(chunk) => {
buffers.push(chunk);
size += chunk.length;
});
req.on('end',() => {
const buf = Buffer.concat(buffers,size);
const str = iconv.decode(buf,'utf8');
req.rowBody = str;
handle(req,res)
})
} else {
}
}
这里我用了一个三方icov-lite,专门用来解析buffer的,尤其是解析中文,因为不解析的情况下存在乱码的风险
举例
我们建立一个html,包含一个form提交表单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test web</title>
</head>
<body>
<div class="root">
<h3>hello build web! </h3>
<form action="/api" method="post">
<label for="username">username</label>
<input type="text" name="username" id="username" /> <br>
<label for="age">username</label>
<input type="text" name="age" id="age" /> <br>
<input type="submit" value="Submit">
</form>
</div>
</body>
</html>
然后通过http.createServer创建服务
const http = require('http');
const querystring = require('querystring');
const iconv = require('iconv-lite');
const port = 8138;
const hostname = '127.0.0.1';
// 判断是否有数据
const hasBody = (req) => {
return 'transfer-encoding' in req.headers || 'content-length' in req.headers;
}
// 解析rowBody数据
const handle = (req,res) => {
if ( req.headers['content-type'] === 'application/x-www-form-urlencoded' ) {
// 表单有数据
const rowBody = querystring.parse(req.rowBody);
console.log(rowBody,'row body')
} else {
}
}
// 流式处理接受过来的数据
const handleBody = (req,res) => {
if ( hasBody(req) ) {
const buffers = [];
let size = 0;
req.on('data',(chunk) => {
buffers.push(chunk);
size += chunk.length;
});
req.on('end',() => {
const buf = Buffer.concat(buffers,size);
const str = iconv.decode(buf,'utf8');
// 将数据暂时保存到rowBody, 或者你也可以使用回调函数
req.rowBody = str;
handle(req,res)
})
} else {
}
}
// 创建服务
const server = http.createServer((req,res) => {
handleBody(req,res);
res.end('you already have a cookie && hello build web & hello cookie!')
})
// 开启服务
server.listen(port,hostname,() => {
console.log(`its running: http://${hostname}:${port}`,)
})
此时,当我们点击表单的提交按钮,服务端就能接收到数据
以上,便是普通上传的全部,感兴趣的帮忙点个赞,支持支持~