node

第一部分 后端的规范与思想

分层

(1)web层:接受和发送HTTP请求的,封装;web层 controller层。
(2)业务逻辑层(服务层 ****service):
(3)DAO层:DataBase(DB):存数据
(4)业务:对{对象}进行操作
如果要存储:对象转为数据
如果要读取:数据转为对象
(5)持久层:存在磁盘上 使用数据库

每层的命名

每层都创建一个文件夹,针对不同功能分类
web层:LoginController登录注册(接收参数,判断是否非法,传给服务层)
服务层:LoginServie(获取用户名密码,进行比较)
DAO层:LoginDAO(从数据库获取数据,并转换为对象)
Domain:User
设计模式:单一职责原则

模块化

  1. require(“./test.js”)
var test = require("./test.js");   //返回一个模块对象 ,未暴露接口时,此时test是空对象{};
1
  1. module.exports(是空对象)暴露接口 此时test是有属性的对象
test  =  { a: 1, b: 'abc' }  
1

注意:require与module.exports的使用遵循开闭原则,即不但需要引用还需要允许引用 3. exports也可以暴露接口

exports与module.exports的区别

两个空对象地址相同时,两个对象才==
exports与module.exports最开始的时候指向同一个地址
exports = a;指向第二个地址 , module.exports = b;指向第三个地址
它们都不指向开始的地址。在导出的时候,导出module.exports的地址里的对象。
导出的永远是对象 module.exports。
永远用 module.exports导出。

nodejs概述

  1. nodejs的模块是运行在一个函数当中的。
funtion ( exports, require, module, __filename, __dirname ) {
    console.log(require);//函数
    console.log(module);//对象
    console.log(exports);//空对象
    console.log(__dirname);//当前文件路径 ——>E:\learn\nodejsChangLiFeng\nodejs3
    console.log(__filename);//文件名全称-->E:\learn\nodejsChangLiFeng\nodejs3
    return module.exports;
};
    console.gog(arguments);// ---->0 : {}    1 : require    2 :module   3 :__filename   4 :  __dirname
    arguments[0] == exports  //true
    arguments[1] == require  //true
    arguments[2] == module  //true
1
2
3
4
5
6
7
8
9
10
11
12
  1. arguments[2] == module里的parent和children
    children里存引用的模块:
    parent里存谁引用的我
    paths里存的路径是寻找node_modules文件的从当前位置一级一级往上找

第二部分 基础API

NET模块

  1. net模块常用事件、方法和属性
    net

  2. 服务端代码使用示例server.js

var net = require("net");

var server = net.createServer();//服务端创建服务
server.listen(12306,"127.0.0.1");//服务端开发地址+端口
//listening是监听服务端是否启动
server.on("listening",function () {
    console.log("服务已启动")
});
//connection是监听服务端是否有新的连接,接收一个socket代表客户端的参数
server.on("connection",function (socket) {
    console.log("有新的连接");
    //监听客户端发来的数据
    socket.on("data", function (data) {
        console.log(data.toString());
        //向客户端发消息
        socket.write("hello client!");
    });
    //监听客户端关闭事件
    socket.on("close", function () {
        console.log("客户端已关闭!");
        //客户端关闭后,关闭服务端
        server.close();
    });
});
//监听服务端是否关闭
server.on("close", function () {
    console.log("连接已经关闭!");
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  1. 客户端代码使用示例client.js
var net = require("net");
var socket = net.connect(12306, "127.0.0.1");//客户端去连接端口

//监听客户端的是否连接服务端
socket.on("connect", function () {
    console.log("客户端已连接到服务器");
    console.log(socket.remoteAddress);//远端地址 127.0.0.1
    console.log(socket.remotePort);//远端端口 12306
    console.log(socket.localAddress);//本地地址 127.0.0.1
    console.log(socket.localPort);//本地端口 52690
});
//向服务端发数据
socket.write("hello server!");
//监听服务端发来的数据
socket.on("data", function (data) {
    console.log(data.toString());
    //关闭连接
    socket.end();
});
//监听客户端关闭事件
socket.on("close", function () {
    console.log("客户端已关闭!")
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  1. setTimeout事件用法
    服务端代码使用示例server.js
var net = require("net");

var server = net.createServer();//服务端创建服务
server.listen(12306,"127.0.0.1");//服务端开发地址+端口
//listening是监听服务端是否启动
server.on("listening",function () {
    console.log("服务已启动")
});
1
2
3
4
5
6
7
8

客户端代码使用示例client.js

var net = require("net");

var socket = net.connect(12306, "127.0.0.1");//客户端去连接端口
//客户端接收数据的延迟时限,即多久之内应接收数据
socket.setTimeout(2000);
socket.on("connect", function () {
    console.log("客户端已连接到服务器");
});
//监听setTimeout限时事件
socket.on("timeout", function () {
    console.log("超时了!");
});
1
2
3
4
5
6
7
8
9
10
11
12
  1. 实现与浏览器通讯
var net = require("net");
var server = net.createServer();
server.listen(12306,"127.0.0.1");
server.on("listening",function () {
    console.log("服务已启动");
});
server.on("connection",function (socket) {
   console.log("有新的连接");
   socket.on("data",function (data) {
       console.log(data.toString());//HTTP请求头
      var request = data.toString().split("\r\n");//拿到请求头第一行GET / HTTP/1.1
      var url = request[0].split(" ")[1];//截取请求头第一行中的路径
      console.log(url);
   });
    //向浏览器传数据,这是最简写法
    socket.write("HTTP 200OK\r\nContent-type:text/html\r\n\r\n<html><body>hello!!</body></html>    ");
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  1. 搭建最简易服务器
    1️⃣ 配置文件-- sever.conf --:写配置文件时,不要有空格!!!
port=12306
path=/web
path_position=relative
1
2
3

2️⃣ 操作配置文件:注意别有空格

var conf = fs.readFileSync("sever.conf");//读取配置文件(读出来的是16进制数)
    console.log(conf.toString());//调用toString()方法取到数据
var confs = conf.toString().split("\r\n");//利用换行符"\r\n"拆分,得到数组
for (var i = 0; i < confs.length; i++) {
    var tempConf = confs[i].split("=");//利用等号拆分,得到属性名和属性值
    if (tempConf.length < 2) {
        continue;
    } else {
        globalConf[tempConf[0]] = tempConf[1];//以键值对的形式存到对象里
    }
}
//判断文件配置为绝对路径,还是相对路径,从而赋值给对象
if (globalConf["path_position"] == "relative") {//绝对路径
    globalConf.basePath = __dirname + globalConf.path;
} else {//相对路径
    globalConf.basePath = globalConf.path;
}
console.log(globalConf.basePath);
module.exports = globalConf;//把处理好的值暴露出去
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

3️⃣服务器端代码:注意浏览器的URL要写出请求哪个页面,要判断好路径

var net = require("net");//引入net模块
var fs = require("fs");//引入文件模块
var globalConf = require("./conf");//引入配置文件的JS文件

var server = net.createServer();//创建一个服务器
server.listen(globalConf.port, "127.0.0.1");//监听
server.on("listening", function () {
    console.log("服务已启动");//服务启动后可运行的回调函数
});
//服务器请求的运行过程
server.on("connection", function (socket) {//监听是否有连接
    socket.on("data", function (data) {//监听客户端发的数据
        var url = data.toString().split("\r\n")[0].split(" ")[1];
            console.log(url);
        try {
            var dataFile = fs.readFileSync(globalConf["basePath"] + url);
            socket.write("HTTP/1.1 200OK\r\n\r\n" );//写响应头,便于下一步发送文件
            socket.write(dataFile);//发送请求的页面
        } catch (e) {
            //如果请求不到就404
            socket.write("HTTP/1.1 404NotFound\r\n\r\n<html><body><h1>404 Not Found</h1></body></html>");
        }
        socket.end();
    });
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

HTTP模块--搭建服务器

  1. HTTP底层是用net模块写的,是基于TCP/IP协议的,要深入学习node必须会net模块,但一般项目很少用到net模块。

服务器搭建的结构

page-->文件夹用来放页面
web----接受web请求的
server----->写服务的
dao层----->联系数据库

http

前端请求可以分为两种1️⃣静态资源html,js,img 等等;2️⃣动态资源-----用户名,密码等等。需要操作数据库

代码示例

//server.conf服务器配置文件
port=12306
page_path=page
static_file_type=.html|.js|.css|.jpg|.gif|.ico
web_path=web
log_path=log/
log_name=server.log
1
2
3
4
5
6
7
//config.js加载服务器配置文件的文件
//解析配置文件的js
var fs = require("fs");
var globalConfig = {};
var conf = fs.readFileSync("./server.conf");
var configArr = conf.toString().split("\r\n");
for (var i = 0; i < configArr.length; i++) {
    globalConfig[configArr[i].split("=")[0]] = configArr[i].split("=")[1];//配置文件里的key   与  value
}
//将静态文件后缀的参数拆分为数组
if (globalConfig.static_file_type) {
    globalConfig.static_file_type = globalConfig.static_file_type.split("|");
} else {
    throw new Error("配置文件异常,缺少:static_file_type")//提示需要有这个配置参数
};
module.exports = globalConfig;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//index.js服务器开启运行的代码
// 服务器配置文件
var http = require("http");//引入HTTP模块,底层用的是NET模块
var url = require("url");//引入url模块,为了使用url的方法取url方便
var fs = require("fs");//引用文件模块,用来读取文件
var globalConfig = require("./config");//引入读取配置文件的文件,取到配置文件数据
var loader = require("./loader");//引入自动加载浏览器请求
var log = require("./log");//引入日志处理的js文件
//开启服务器
http.createServer(function (request, response) {  //request是请求内容     response是响应内容
    //request.url取到url及拼接到url后面的数据
    //url.parse(request.url)拿到请求的url的相关的所有属性的对象
    //url.parse(request.url).pathname拿到请求的url的相关的所有属性的对象中的URL
    var pathName = url.parse(request.url).pathname;//取到路径
    var params = url.parse(request.url, true).query;//查询url拼接的参数,true设置好后,取到的是对象
    var isStatic = isStaticsRequest(pathName);//通过下面定义的函数,判断
    log(pathName);//打印取到路径到日志里
    //判断请求的是静态文件(如HTML文件)还是动态的数据(ajax请求数据)
    if (isStatic) {//请求的静态文件
        // console.log(globalConfig["page_path"] + pathName);
        try {
            var data = fs.readFileSync(globalConfig["page_path"] + pathName);//读取文件
            // console.log(data.toString());
            response.writeHead(200);//响应头
            response.write(data);//文件写给给浏览器
            response.end();//响应结束后停止
        } catch (e) {
            //没找到文件就给404
            response.writeHead(404);
            response.write("<html><body><h1>404 NotFound</h1></body></html>");
            response.end();
        }
    } else {//请求的动态的数据
        if (loader.get(pathName) != null) {
            try {
                loader.get(pathName)(request, response);//返回数据,loader.get(pathName)取到方法,(request, response)方法的参数
            } catch (e) {
                //URL下没找到数据,就报服务器错误
                response.writeHead(500);
                response.write("<html><body><h1>500 BadServer</h1></body></html>");
                response.end();
            }
        } else {
            //没找到动态数据的URL就报404
            response.writeHead(404);
            response.write("<html><body><h1>404 NotFound</h1></body></html>");
            response.end();
        }
    }
}).listen(globalConfig["port"]);//取配置文件里的端口号
log("服务已启动");//打印日志
//判断请求的URL是不是配置文件中所规定的静态文件,是返回true,不是返回false
function isStaticsRequest(pathName) {
    for (var i = 0; i < globalConfig.static_file_type.length; i++) {
        var temp = globalConfig.static_file_type[i];
        //判断url后缀是否为配置文件里静态资源设置的后缀    pathName是取到的路径   temp是配置文件里的后缀
        if (pathName.indexOf(temp) == pathName.length - temp.length) {
            return true;
        }
    }
    return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//loader.js自动加载web里的文件
var fs = require("fs");//引入文件模块
var globalConfig = require("./config");//引入读取配置文件的文件,取到配置文件数据
var pathMap = new Map();
var files = fs.readdirSync(globalConfig["web_path"]);//读取这个路径下的所有文件(这个路径下的文件是对应处理个页面动态数据请求的文件)
var controllerSet = [];
for (var i = 0; i < files.length; i++) {
    var temp = require("./" + globalConfig["web_path"] + "/" + files[i]);//引入该路径下的文件(这里引用了loginController.js里path)
    if (temp.path) {
        for (var [key,value] of temp.path) {
            // console.log(key);
            // console.log(value);
            if (pathMap.get(key) == null) { //看看key是否存在
                pathMap.set(key, value);
            } else {
                //用来区分不同响应的js文件里的方法名相同,造成执行时的错误
                throw new Error("url_path异常,url:" + key);//说明key重名了
            }
            controllerSet.push(temp);
        }
    }

}
// console.log(controllerSet);
module.exports = pathMap;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//login.html请求的静态页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="data:image/ico;base64,aWNv">
    <title>Title</title>
    <script src="login.js" type="text/javascript"></script>
</head>
<body>
    hello, world


</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//login.js请求的静态页面的js文件,里面是动态数据请求
window.onload = function () {
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open("GET", "/getData", true);
    xmlHttp.send();
    xmlHttp.onreadystatechange = function () {
        if (xmlHttp.readyState === 4) { // 成功完成
            // 判断响应结果:
            if (xmlHttp.status === 200) {
                // 成功,通过responseText拿到响应的文本:
                console.log("ajax");
                console.log(xmlHttp.responseText);

            } else {
                // 失败,根据响应码判断失败原因:
                console.log("2");
                return fail(xmlHttp.status);

            }
        } else {
            console.log("3");
// HTTP请求还在继续...
        }
    };
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//loginController.js接收所有login里面页面ajax请求,并返回数据
var path = new Map();
function getDtata(request, response) {
    response.writeHead(200);
    response.write("hello");
    response.end();
}
path.set("/getData", getDtata);//(login页面请求动态数据的路径,接收请求后执行的方法)
function getDtata2(request, response) {
    // response.writeHead(200);
    // response.write("ho");
    // response.end();
}
path.set("/getData2", getDtata2);//(路径   ,   方法)
module.exports.path = path;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//log.js打印日志的方法
var fs = require("fs");//引入文件模块
var globalConfig = require("./config");//引入配置文件,主要是为日志文件写路径
var fileName = globalConfig.log_path + globalConfig.log_name;//注意这里的路径在配置文件里的格式   即后面加/
// fs.writeFile(fileName,"asd",function () { });//异步写文件
// fs.writeFileSync(fileName,"asd");//同步写文件
function log(data) {
    //向fileName这个文件里写传入得参数
    fs.appendFile(fileName,data + "\n",function () { });//自带追加功能
    // fs.writeFile(fileName,data + "\n",{flag:"a"},function () {
    //     console.log("finish")
    // });//异步写文件
};
module.exports = log;
1
2
3
4
5
6
7
8
9
10
11
12
13
14

下图为文件读写的方法里的flag参数,用于控制读、写、创建的权限
fs

//server.log打印出来的日志文件
服务已启动
/login.html
/login.js
/getData
1
2
3
4
5

基于HTTP模块--连接MySQL(上述示例的补充)




 


//数据库中的表
1	收到了	12	1  
3	姐将	18	1  
4	对看	19	2  
5	方看	17	2  
1
2
3
4
5

web层调用service层;service层调用dao层;dao层调用数据库。




 








//dbutil.js连接数据库,的公用文件
var mysql = require("mysql");//引入MySQL,但先要安装MySQL
//连接数据库
var connection = mysql.createConnection({
   host: "127.0.0.1",//服务器定义的地址
   port: "3306",//MySQL的端口号
   user: "root",//MySQL的账户
   password: "bob*01",//MySQL的密码
   database: "school"//MySQL里要用的数据库
});
module.exports = connection;
1
2
3
4
5
6
7
8
9
10
11



 






































//studentDao.js针对student数据库的操作文件
var connection = require("./dbutil");
//取到数据库中student表中所有数据
function queryAllStudent(sucess) {
    var querySql = "select * from student;";//查询student表中所有数据
    connection.connect();//连接数据库
    //如果连接成功,执行querySql之后,执行回调函数
    connection.query(querySql,function (err, result) {
        if(err == null) {
            console.log(result);
            sucess(result);
        }else {
            console.log(err);
        }
    });
    connection.end();//查询之后,必须关闭
};

// queryAllStudent();
//以classNum, age参数查询数据库
function queryStudentByClassAndAge(classNum, age) {
    var querySql = "select * from student where class = ? and age = ?;";
    var queryParams = [classNum, age];
    connection.connect();
    //第二个参数传多个参数时,要用数组
    connection.query(querySql,queryParams,function (err, result) {
        if(err == null) {
            console.log(result);
        }else {
            console.log(err);
        }
    });
    connection.end();
};

// queryStudentByClassAndAge(1, 18);
//web层调用service层;service层调用dao层;dao层调用数据库。
module.exports = {
    "queryAllStudent": queryAllStudent,
    "queryStudentByClassAndAge": queryStudentByClassAndAge
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41



 




//studentsService.js处理web层的数据请求
var strdentDao = require("../dao/studentDao");

function queryAllStudent(sucess) {
    strdentDao.queryAllStudent(sucess);
};
module.exports = {"queryAllStudent": queryAllStudent};
1
2
3
4
5
6
7



 

















//接收所有login里面页面请求
var studentService = require("../service/studentsService");
var path = new Map();
function getData(request, response) {
    // response.writeHead(200);
    // response.write("hello");
    // response.end();
    studentService.queryAllStudent(function (result) {
        var resArr = [];//收集数据的空数组
        for (var i = 0 ; i < result.length ; i ++) {
            resArr.push(result[i].name);//数据中name全部存入数组中
        };
        response.write(resArr.toString());//写回给浏览器
        response.end();
    });
}
path.set("/getData", getData);//(路径   ,   方法)

module.exports.path = path;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Express

基于 Node.js 平台,快速、开放、极简的 Web 开发框架

下面实例主要是完成后端的基础任务,具体见下图

express

文件结构不变,由于涉及文件上传下载,加入文件夹file,存放上传文件。

其中dao文件加下的dbutil.js、根目录下的server.conf、loader.js文件不变。




 
























//应用express后的index.js
var app = new express();//创建express实例
var uploadSingle = multer({dest:"./file/"});//指定文件上传到哪里

app.use(express.static(globalConfig["page_path"]));//使用static方法加载某路径下的所有静态文件,不用单独写静态文件判断的配置了!
app.use(cookie());//使用cookie

app.get("/api/*", function (request, response, next) {//为/api路径下的所有动态请求设置拦截
    if(request.cookies.id) {//读取cookie中的某个属性值,如果存在就执行next()
        console.log(request.cookies.id);
        next();//继续下面的操作
    }else {//如果不存在
        response.redirect("/login.html");//重定向到登录页面
    }
 });


app.get("/api/getAllStudent", loader.get("/api/getAllStudent"));//通过get方法,获取动态请求,并得到数据
app.get("/api/addStudent", loader.get("/api/addStudent"));//通过get方法,获取动态请求,并得到数据
app.get("/login", loader.get("/login"));//通过get方法,获取动态请求,并得到数据
//上传文件
app.post("/upload", uploadSingle.single("file"), loader.get("/upload"));//uploadSingle.single("file")指定上传字段
//显示图片
app.get("/getPic", loader.get("/getPic"));

app.listen(globalConfig["port"]);//监听端口号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27



 









//config.js
//解析配置文件的js
//使用express后,这里只需写这些就够了
var fs = require("fs");
var globalConfig = {};
var conf = fs.readFileSync("./server.conf");
var configArr = conf.toString().split("\r\n");
for (var i = 0; i < configArr.length; i++) {
    globalConfig[configArr[i].split("=")[0]] = configArr[i].split("=")[1].trim();//配置文件里的key   与  value
}

module.exports = globalConfig;
1
2
3
4
5
6
7
8
9
10
11
12



 




















//web文件夹下getPic.js下载图片(文件),并发送至浏览器
var url = require("url");
var path = new Map();
var fs = require("fs");

function getPic(request, response) {
    var params = url.parse(request.url, true).query;//取到请求图片的路径

    try {
        var data = fs.readFileSync("./" + params.path);//读取文件
        response.writeHead(200);
        response.write(data);//读取到的文件给浏览器
        response.end();
    } catch (e) {
        response.writeHead(404);
        response.end();
    }

}

path.set("/getPic", getPic);

module.exports.path = path;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23



 







































//web文件夹下studentController.js ,主要关注下面用户登录的功能
var studentDao = require("../dao/studentDao");
var url = require("url");
var path = new Map();


function getAllStudent(request, response) {
    studentDao.queryAllStudent(function (result) {
        response.writeHead(200,{"Content-Type": "text/html:charset=utf-8"});
        response.write(JSON.stringify(result));
        response.end();
    })
}
path.set("/api/getAllStudent", getAllStudent);

function addStudent(request, response) {
    var params = url.parse(request.url,true).query;
    studentDao.insertStudent(params.name, params.age,params.stu_class,function (result) {
        response.writeHead(200,{"Content-Type": "text/html:charset=utf-8"});
        response.write("添加成功");
        response.end();
    })
}
path.set("/api/addStudent", addStudent);

function login (request, response) {
    var params = url.parse(request.url,true).query;//取到url上的数据
    studentDao.queryStudentByStuNum(params.stuNum, function (result) {
        var flag = result && result.length > 0 && result[0].pwd == params.pwd ;//对比输入密码与数据库密码是否一致
        console.log(flag);
        if (flag) {
            response.cookie("id", result[0].id);
            response.redirect("/api/getAllStudent");//结果一致跳转页面
        }else {
            response.redirect("/loginError.html");//不一致跳转页面
        }
    })
}
path.set("/login", login);

module.exports.path = path;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42



 


















//web文件夹下upload.js处理上传文件的请求
var fileListDao = require("../dao/fileListDao");

var path = new Map();

function upload(request, response) {
    console.log(request.file.originalname);//原文件名
    console.log(request.file.size);//文件大小
    console.log(request.file.path);//存放的路径(数据流名字)
    console.log(request.cookies.id);//相当于取用户名
    //相当于调用dao里的方法将取到的文件数据写到数据库里
    fileListDao.insertFileList(request.file.originalname, request.file.size, request.file.path, request.cookies.id, function (result) {
        console.log("写库成功");
        response.end(request.file.path);
    })
}

path.set("/upload", upload);

module.exports.path = path;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21



 













//page文件夹下的login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login" method="get">
    <input type="text" name="stuNum">
    <input type="password" name="pwd">
    <input type="submit" value="登录">
</form>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16



 



































//page文件夹下的main.html, 处理文件上传 下载
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        function submitFile() {
            var file = document.getElementById("file").files[0];
            var form = new FormData();
            form.append("file", file);

            var xhr = new XMLHttpRequest();
            xhr.open("post", "/upload", true);
            xhr.onload = function () {
                alert("上传完成!");

            };

            xhr.send(form);
            xhr.onreadystatechange = function () {
                if(xhr.readyState == 4 && xhr.status == 200) {
                    var path = xhr.responseText;//取到想要图片的路径
                    pic.src = "/getPic?path=" + path;//拼接到src上
                }
            }
        }
    </script>
</head>
<body>
    <input type="file" id="file">
    <input type="button" onclick="submitFile()" value="asd">
    <img src="" id="pic">
    <a href="/getPic?path=file\c8a83bcc1a3037b3f5dfa5aaf51be619" download="2.jpg">点击下载</a>
    <a href="/getPic?path=file\fabcc882e58fe230435f362c5cf70cb9" download="新建 Microsoft Word 文档.docx">新建 Microsoft Word 文档.docx</a>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38



 
















































































//dao文件夹下的studentDao, 主要关注学号查询
//studentDao.js针对student数据库的操作文件
var dbutil = require("./dbutil");

//上传数据到数据库
function insertStudent(name, age, stu_class, success) {
    var insertSql = "insert into student (name, age, stu_class) values(?,?,?);";//查询student表中所有数据
    var params = [name, age, stu_class];
    var connection = dbutil.createConnection();//创建新的连接
    connection.connect();//连接数据库
    //如果连接成功,执行querySql之后,执行回调函数
    connection.query(insertSql,params,function (err, result) {
        if(err == null) {
            console.log(result);
            success(result);
        }else {
            throw new Error(err);
        }
    });
    connection.end();//查询之后,必须关闭
}


//取到数据库中student表中所有数据
function queryAllStudent(sucess) {
    var querySql = "select * from student;";//查询student表中所有数据
    var connection = dbutil.createConnection();//创建新的连接
    connection.connect();//连接数据库
    //如果连接成功,执行querySql之后,执行回调函数
    connection.query(querySql,function (err, result) {
        if(err == null) {
            console.log(result);
            sucess(result);
        }else {
            throw new Error(err);
        }
    });
    connection.end();//查询之后,必须关闭
}

// queryAllStudent();
//以classNum, age参数查询数据库
function queryStudentByClassAndAge(classNum, age) {
    var querySql = "select * from student where class = ? and age = ?;";
    var queryParams = [classNum, age];
    var connection = dbutil.createConnection();
    connection.connect();
    //第二个参数传多个参数时,要用数组
    connection.query(querySql,queryParams,function (err, result) {
        if(err == null) {
            console.log(result);
        }else {
            throw new Error(err);
        }
    });
    connection.end();
}

function queryStudentByStuNum (stuNum, success) {
    var querySql = "select * from student where stuNum = ?;";
    var connection = dbutil.createConnection();
    connection.connect();
    connection.query(querySql, stuNum, function (error, result) {
        if (error == null) {
            console.log(result);
            success(result);
        }else {
            throw new Error(error);
        }
    });
}



// queryStudentByClassAndAge(1, 18);
//web层调用service层;service层调用dao层;dao层调用数据库。
module.exports = {
    "queryAllStudent": queryAllStudent,
    "queryStudentByClassAndAge": queryStudentByClassAndAge,
    "insertStudent": insertStudent,
    "queryStudentByStuNum": queryStudentByStuNum,
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83



 























//dao文件夹下fileList.js针对上传的文件信息进行数据库的操作文件
var dbutil = require("./dbutil");

//上传数据到数据库
function insertFileList(fileName, fileSize, filePath, stuNum, success) {
    var insertSql = "insert into file_list (fileName, fileSize, filePath, stuNum) values(?,?,?,?);";//查询student表中所有数据
    var params = [fileName, fileSize, filePath, stuNum];
    var connection = dbutil.createConnection();//创建新的连接
    connection.connect();//连接数据库
    //如果连接成功,执行querySql之后,执行回调函数
    connection.query(insertSql, params, function (err, result) {
        if (err == null) {
            console.log(result);
            success(result);
        } else {
            throw new Error(err);
        }
    });
    connection.end();//查询之后,必须关闭
}


module.exports = {
    "insertFileList": insertFileList,
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26