1. 最终实现的效果
2. 逻辑思路分析图
3. 模块分类
4. 需要使用的第三方包插件
5. 模块分类
app.js(主要用来开启服务器)
//开启服务器
//核心
var http = require("http");
//自定义
var render = require("./render.js");
var router = require("./router.js");
var server = http.createServer();
server.on("request",function(req,res){
//在res中注册一个render方法
render(res);
//为下面代码的执行铺路:下面需要接收路径,根据不同的路径作出不同的处理,我们使用一个单独的模块来完成这个功能
//这个模块我们取名叫做路由
router(req,res);
});
server.listen(3000,function(){
console.log("running");
});
render.js(主要是用来模板渲染)
var fs = require("fs");
var template = require("art-template");
//用来给res对象动态添加一个渲染方法
module.exports = function (res) {
//作用:读取views下面的静态文件
//参数一:url要读取的静态文件的名称 index.html add.html
//参数二:obj 要通过模板引擎渲染的数据
//参数三:callback 给将来调用者设置一个回调函数,读取出数据以后怎么操作由调用者来决定
// 现在callback中有两个参数:第一个参数是err,第二个参数是html
// 由于我们将来对读取出来数据无非作这么几种处理:
// 1)直接返回给浏览器,2)得到一个数据,将数据通过模板引擎进行渲染,渲染以后再返回给浏览器
res.render = function (url,obj,callback) {
//将url转换为可以读取内容的路径
var path = "./views/" + url;
fs.readFile(path,function(err,data){
if(err) {
return callback(err);
}
//将数据进行渲染,并且响应到浏览器中
var html = template.compile(data.toString())(obj || {});
callback(null,html);
});
}
}
router.js(主要是用来路由转发)
var handler = require("./handler.js");
//路由只是用来分发请求,得到请求的路径,并且判断路径,具体做什么事情,这个文件也不管
module.exports = function(req,res){
//先拿到不同的请求
var url = req.url;
var method = req.method;
//判断
if(url == "/" && method == "GET") {
handler.getIndex(req,res);
} else if( url == "/add" && method == "GET") {
handler.getAdd(req,res);
} else if(url =="/upload" && method == "POST") {
handler.postUpload(req,res);
} else if( url == "/add" && method == "POST"){
handler.postAdd(req,res);
} else if (url.indexOf("/node_modules") == 0 || url.indexOf("/img") == 0) {
handler.getStatic(req,res);
}
}
handler.js(主要处理模块)
//负责处理具体的事物
var fs = require("fs");
//第三方
var formidable = require("formidable");
module.exports.getIndex = function(req,res){
//封装读取静态文件的代码
fs.readFile("./data.json",function(err,herosData){
if(err) {
return res.end("失败");
}
res.render("index.html",JSON.parse(herosData.toString()),function(err,html){
if(err) {
return res.end("失败");
}
res.end(html);
});
});
}
module.exports.getAdd = function(req,res){
res.render("add.html",null,function(err,data){
if(err) {
return res.end(err);
}
res.end(data);
});
}
module.exports.postAdd = function(req,res){
res.writeHead(200,{
"content-type": "text/html;charset=utf-8"
});
// 将原来通过data和end事件接收到的参数 改为通过第三方包formidable来接收
//创建一个formidable对象
var form = new formidable.IncomingForm();
// //调用parse方法
// //回调函数的三个参数:
// // 参数一:err:错误信息
// // 参数二:fields 字段 从浏览器端提交到服务器的一些属性
// // 参数三:files 文件 从浏览器端上传过来的文件
// // 由于formidable会将图片自动保存到一个临时目录下,而我们需要将图片保存到img下,所以需要设置一个图片的保存路径
// form.uploadDir = "./img";
// // 由于formidable默认不会保存文件的后缀名,所以我们需要将图片留后缀名
// form.keepExtensions = true;
form.parse(req, function(err, fields, files) {
if(err) {
return res.end("失败");
}
fs.readFile("./data.json",function(err,herosData){
var heros = JSON.parse(herosData.toString());
//根据得到的参数创建一个对象
var obj = {};
obj.name = fields.name;
obj.gender = fields.gender;
//得到heros中最后一条数据的id
var id = heros.heros[heros.heros.length - 1].id + 1;
obj.id = id;
// obj.img = "/" + files.img.path;
obj.img = fields.img;
//将对象重新追倒hero中
heros.heros.push(obj);
//重新将对象写入到data.json中
fs.writeFile("./data.json",JSON.stringify(heros,null," "),function(err){
if(err) {
return res.end(retMsg(1,"失败"));
}
// res.end("");
//返回的数据是交给浏览器中的异步对象的,而异步对象需要的一个json格式的字符串
//将retobj对象作为返回给浏览器的数据,有这么几属性:
// statu: 表示的是当前操作的状态码: 0 成功 1 失败
// msg: 表示当前操作的 文本信息
// var retObj = {
// statu: 0,
// msg: "操作成功"
// };
// res.end(JSON.stringify(retObj));
res.end(retMsg());
});
});
})
}
module.exports.postUpload = function(req,res){
var form = new formidable.IncomingForm();
form.uploadDir = "./img";
form.keepExtensions = true;
form.parse(req, function(err, fields, files) {
if(err) {
return res.end(retMsg(1,"失败"));
}
var imgName = "/" + files.img.path;
res.end(retMsg(0,"成功",imgName));
});
}
module.exports.getStatic = function(req,res) {
var path = "." + req.url;
fs.readFile(path,function(err,data){
if(err) {
return res.end("失败");
}
res.end(data);
});
}
//设置一个统一的返回对象
// statu:返回对象的状态 0成功 1失败
// msg:返回对象信息
// imgName: 返回对象的图片名称
function retMsg(statu,msg,imgName) {
var obj = {};
obj.statu = statu || 0;
obj.msg = msg || "成功";
obj.imgName = imgName || "";
//将对象转为字符串返回
return JSON.stringify(obj);
}
views下index.html以及add.html的内容
index.html
Hero - Admin
王者荣耀 英雄管理器
add.html(异步传输用这个)
Document
add.html(同步传输的话用这个)
Document
data.json(模拟数据库存放的数据)
{
"heros": [
{
"id": 1,
"name": "亚瑟",
"gender": "男",
"img": "/img/1.jpg"
},
{
"id": 2,
"name": "李白",
"gender": "男",
"img": "/img/2.jpg"
},
{
"id": 3,
"name": "安奇拉",
"gender": "女",
"img": "/img/3.jpg"
},
{
"id": 4,
"name": "虞姬",
"gender": "女",
"img": "/img/4.jpg"
}
]
}
开启node