目录
一.重构路由代码
看到上篇文章里的server.js文件中的服务器功能函数,如果地址过多的时候,还是一个个if,else,那么代码就太过臃肿,所以需要将路由代码重构。
index.js主入口文件:
handle根据路径寻找对应的函数名
//入口
var server=require("./server.js");
var handler=require("./handler");
var route=require("./router.js");
//req.url的字典
var handle={};
handle["/"]=handler.home;
handle["/home"]=handler.home
handle["/user"]=handler.user
handle["/list"]=handler.list
//将handle传入,根据地址寻找对应函数名
//参数route是回调函数的写法,传入函数名,外层函数体内再执行回调函数
server.startServer(route,handle);
server.js:
服务器启动函数
var http=require("http");
//启动服务器
function startServer(route,handle){
var server=http.createServer(function(req,res){
//注意req.url是主机名:端口号后面的地址内容
route(handle,req.url,res);
})
server.listen(3000,"127.0.0.1");
console.log("服务器运行在3000端口上");
}
//将启动服务器函数导出
module.exports={
startServer
}
router.js:
var fs=require("fs");
//注意pathname是主机名:端口号后面的地址内容,对应于req.url
function route(handle,pathname,res){
if(typeof handle[pathname]==='function'){
//调用函数,handle[pathname]就是函数,请看index.js文件
handle[pathname](res);
}else{
res.writeHead(404, { "Content-Type": "text/html" });
fs.createReadStream(__dirname+"/404.html","utf-8").pipe(res);
}
}
module.exports=route;
handler.js:
var fs=require("fs");
var data=require("./data.js");
// / /home
function home(response){
response.writeHead(200, { "Content-Type": "text/html" });
fs.createReadStream(__dirname+"/home.html","utf-8").pipe(response);
}
// /user
function user(response){
response.writeHead(200, { "Content-Type": "application/json" });
response.end(JSON.stringify(data));
}
// /list
function list(res){
res.writeHead(200,{"Content-Type":"application/json"});
//返回地址?后面的参数,以json的形式
res.end(JSON.stringify(data));
}
//将这两个功能函数导出
module.exports={
home,
user,
list
}
404.html:
<!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>Document</title>
</head>
<body>
404页面!
</body>
</html>
home.html:
<!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>Document</title>
</head>
<body>
Home页面!
</body>
</html>
data.js:
这次json数据换成js的方式表示试试,所以得导出
var data ={
name:"kd",
age:20
};
module.exports=data;
二.使用Get或Post发送数据
1.get方式
对上面的那个例子部分文件稍加修改:
server.js:
var http=require("http");
var url=require("url");
//启动服务器
function startServer(route,handle){
var server=http.createServer(function(req,res){
//获得地址里的参数
//parse里的第二个参数设为true是返回一个对象,设为false返回字符串
var params=url.parse(req.url,true).query;
//主机号:端口号和?之间的那段地址
//如果仍然用req.url,那么地址后面加了参数之后在route函数只能就会跳转到404页面
var pathname=url.parse(req.url).pathname;
console.log(pathname);
//注意req.url是主机名:端口号后面的地址内容
route(handle,pathname,res,params);
})
server.listen(3000,"127.0.0.1");
console.log("服务器运行在3000端口上");
}
//将启动服务器函数导出
module.exports={
startServer
}
router.js:
var fs=require("fs");
//注意pathname是主机名:端口号后面的地址内容,对应于req.url
//handle是pathname的字典
//params是地址中?后面的参数
function route(handle,pathname,res,params){
if(typeof handle[pathname]==='function'){
//调用函数,handle[pathname]就是函数,请看index.js文件
handle[pathname](res,params);
}else{
res.writeHead(404, { "Content-Type": "text/html" });
fs.createReadStream(__dirname+"/404.html","utf-8").pipe(res);
}
}
module.exports=route;
handler.js:
var fs=require("fs");
var data=require("./data.js");
// / /home
function home(response){
response.writeHead(200, { "Content-Type": "text/html" });
fs.createReadStream(__dirname+"/home.html","utf-8").pipe(response);
}
// /user
function user(response){
response.writeHead(200, { "Content-Type": "application/json" });
response.end(JSON.stringify(data));
}
// /list
function list(res,params){
res.writeHead(200,{"Content-Type":"application/json"});
//返回地址?后面的参数,以json的形式
res.end(JSON.stringify(params));
}
//将这两个功能函数导出
module.exports={
home,
user,
list
}
其他文件不变,运行之后,在浏览器中输入localhost:3000/list?name=jack&sex=male试试。
输出:
终端输出:
服务器运行在3000端口上
/list
浏览器输出:
2.post方式
在get方式基础上修改之后根据提交信息的方式不同,自动区分get或post方式
home.html:
<!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>Document</title>
</head>
<body>
Home页面!<br>
<!-- 向http://localhost:3000/list提交数据 -->
<form action="/list" method="post">
name:<input type="text" name="username">
password:<input type="password" name="password"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
server.js:
var http = require("http");
var url = require("url");
var querystring = require("querystring");
//启动服务器
function startServer(route, handle) {
var server = http.createServer(function (req, res) {
//主机号:端口号和?之间的那段地址
//如果仍然用req.url,那么地址后面加了参数之后在route函数只能就会跳转到404页面
var pathname = url.parse(req.url).pathname;
console.log(pathname);
//存放post数据
var data = [];
req.on("error", function (err) {
console.log(err);
}).on("data", function (chunk) {
data.push(chunk);
}).on("end", function () {
if (req.method === "POST") {
data = Buffer.concat(data).toString();
//querystring.parse()方法将URL查询字符串(str)解析为键值对的集合。
route(handle, pathname, res, querystring.parse(data));
} else {//GET方式
//获得地址里的参数
//parse里的第二个参数设为true是返回一个对象,设为false返回字符串
var params = url.parse(req.url, true).query;
//注意req.url是主机名:端口号后面的地址内容
route(handle, pathname, res, params);
}
})
})//createServer
server.listen(3000, "127.0.0.1");
console.log("服务器运行在3000端口上");
}
//将启动服务器函数导出
module.exports = {
startServer
}
测试post方式:
输入http://localhost:3000,输入数据
三.npm命令
npm
为你和你的团队打开了连接整个 JavaScript 天才世界的⼀扇⼤⻔。它是世界上最⼤的软件注册表,每星期⼤约有 30 亿次的下载量,包含超过 600000 个 包(
package) (即,代码模块)。来⾃各⼤洲的开源软
件开发者使⽤ npm 互相分享和借鉴。包的结构使您能够轻松跟踪依赖项和版本。
我们使⽤npm也避免了重复造轮⼦的问题。
安装依赖
我们需要第三⽅依赖,可以直接通过npm进⾏下载,例如:
npm install express
cnpm镜像
npm是在远程仓库下载,我们知道他的仓库并不在国内,所以,我们需要找⼀个国内的仓库镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
能用npm还是用npm,因为cnpm可能存在一些问题,下载的包不全之类的
package.json
因为
node_modules
⽂件依赖⽂件太多,⽽且他也不属于我们的源代码,所以我们在上传源代码的时候并
不会上传
这个⽂件夹,那么别⼈如何知道我们安装过了哪些包呢?
运行 npm init
初始化⼀个
package.json
⽂件
{
"name": "1",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "ISC"
}
然后在安装依赖的时候。我们需要在命令⾏上加⼊
--save或者--sage-dev
npm install --save express
npm install --save-dev gulp
上述两种⽅式,区别在于
--save
是⽣产环境,
--save-dev
是开发环境
加上上面的前缀再去下载包时,也会自动修改
package.json文件,记录下载了什么模块,如下:
"dependencies": {
"express": "^4.16.2"
},
"devDependencies": {
"gulp": "^3.9.1"
},
有了上述的描述,我们删除
node_modules
别⼈就可以根据描述来进⾏安装了,直接运行下面的命令即可安装所需模块,而不用再手动一个个安装!
npm install
scripts脚本
我们还有⼀个scripts脚本可以使⽤,⼀个项⽬的⼊⼝⽂件不是固定的,所以如果别⼈拿到你的代码,不知道你的⼊⼝⽂件,则⽆法运⾏你的项⽬,下⾯的脚本可以有效的解决这个问题
"scripts": {
"start": "node app.js"
},
执行命令npm run start即可执行程序。
四.nodemon
nodemon是⼀种⼯具,可以⾃动检测到⽬录中的⽂件更改时通过重新启动应⽤程序来调试基于node.js的应⽤程序。
npm install -g nodemon
有了这个命令,我们就不再需要每次修改完毕代码进⾏重启了,他可以检测⽂件的改变⽽⾃动重启
nodemon app.js
当然。nodemon不仅有以上功能,他还有很多配置,但是对于⽬前我们的需求来说不太需要,在这⾥不做叙述。