代码注释
复杂处理器(可处理post和getqing求)
var http = require('http');
var path = require('path');
var fs = require('fs');
var url = require('url');
var routes = {
'/a': function(req, res){
res.end(JSON.stringify(req.query));
},
'/b': function(req, res){
res.end('match /b');
},
'/a/c': function(req, res){
res.end('match /a/c');
},
'/search': function(req, res){
res.end('username='+req.body.username+',password='+req.body.password);
}
};
var server = http.createServer(function(req, res){
routePath(req, res);
});
server.listen(8080);
console.log('visit http://localhost:8080');
function routePath(req, res){
var pathObj = url.parse(req.url, true);
var handleFn = routes[pathObj.pathname];
if(handleFn){
req.query = pathObj.query;
//参考 https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/
// post json 解析
var body = '';
req.on('data', function(chunk){
body += chunk;
}).on('end', function(){
req.body = parseBody(body);
handleFn(req, res);
});
}else {
staticRoot(path.resolve(__dirname, 'static'), req, res);
}
}
function staticRoot(staticPath, req, res){
var pathObj = url.parse(req.url, true);
var filePath = path.join(staticPath, pathObj.pathname);
fs.readFile(filePath, 'binary', function(err, content){
if(err){
res.writeHead('404', 'haha Not Found');
return res.end();
}
res.writeHead(200, 'Ok');
res.write(content, 'binary');
res.end();
});
}
function parseBody(body){
console.log(body);
var obj = {};
body.split('&').forEach(function(str){
obj[str.split('=')[0]] = str.split('=')[1];
});
return obj;
}
1.程序入口:
var server = http.createServer(function(req, res){
routePath(req, res);
});
当一个请求进来之后,进入到http.createServer
这个逻辑里面,然后会调用routePath(req, res)
这个函数去处理这个请求和响应。
2.function routePath(req, res){}:
url.parse(req.url, true) :
解析url
routes[pathObj.pathname] :
得到 pathname,也就是路由。
得到pathname
后,从 routes
里根据pathname
, 输入pathname
里面 的 key 去匹配看能不能得到它的值,如果pathname
这里面没有,那就会得到undefined
,所以handleFn
就是undefined
。
如果routes
里找不到的话,就进入 else 的逻辑让它去把这个请求当成静态文件去处理 staticRoot
。
else{
staticRoot(path.resolve(__dirname, 'static'), req, res);
}
如果routes
里找到了,匹配上了,就进入到这个逻辑:
req.query = pathObj.query;
var body = '';
req.on('data', function(chunk){
body += chunk;
}).on('end', function(){
req.body = parseBody(body);
handleFn(req, res);
});
我们把url
请求的query
放到 req
上req.query = pathObj.query
,这样的话我们在routes
中的地方就可以直接使用 req.query
{
'/a': function(req, res){
res.end(JSON.stringify(req.query));
},
对于 POST 形式的东西,因为 POST 请求的数据它并不在 url 里面,所以它有一些特殊。我们可以通过req.on('data', ...)
就可以得到里面的数据;
然后 req.on('end', ...)
这个数据就全都完成了,就可以通过调用parseBody(body)
把这个数据给解析出来,解析成一个对象然后放在 body( req.body)
上;
req.body = parseBody(body)
parseBody(body) 这个 body 得到的值其实就是 key = value,a = b,就是 key = value & key = value 的形式,我们把这个格式变成一个对象:
function parseBody(body){
console.log(body);
var obj = {};
body.split('&').forEach(function(str){
obj[str.solit('=')[0]] = str.split('=')[1];
});
return obj;
}
得到body
这个对象之后我们就可以调用 handleFn(req, res)
进入到对应的逻辑下。
换句话说,当用户调用的是'/a'
,又有 GET 也有 POST 数据,那它就会执行'/a'
的函数。
req.query
就是 GET 对应的数据,req.body
就是 POST 对应的数据。那我们就可以直接获取里面的东西,比如说req.body.username
。在这里得到数据之后,我们就可以模拟这个数据,就可以 mock 了。 就可以做各种判断了。
nodejs 中间件:就是处理路由的。
中间件:即在中间放一个物件,处理你的请求。