Node-Express入手

入手

先使用脚手架搭建一个项目

cnpm install express-generator -g

帮助菜单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
express -h

Usage: express [options] [dir]

Options:

-h, --help output usage information
-V, --version output the version number
-e, --ejs add ejs engine support (defaults to jade)
--hbs add handlebars engine support
-H, --hogan add hogan.js engine support
-c, --css <engine> add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
--git add .gitignore
-f, --force force on non-empty directory

进入目录后创建项目

express myapp
cnpm i

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.
├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
└── views
├── error.jade
├── index.jade
└── layout.jade

7 directories, 9 files

./bin/www为启动文件,使用命令npm start启动

package.json

不知道为啥,会有缺少一堆文件,按照提示安装完之后。
待会儿会用到MySQL,使用sequelize这个ORM框架。并且需要mysql2这个包

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
{
"name": "myapp",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.18.2",
"cookie-parser": "~1.4.3",
"debug": "~2.6.9",
"depd": "^1.1.1",
"ee-first": "^1.1.1",
"ejs": "^2.5.7",
"encodeurl": "^1.0.1",
"escape-html": "^1.0.3",
"express": "~4.15.5",
"express-session": "^1.15.6",
"finalhandler": "^1.1.0",
"jade": "~1.11.0",
"merge-descriptors": "^1.0.1",
"morgan": "~1.9.0",
"mysql": "^2.15.0",
"mysql2": "^1.5.1",
"on-finished": "^2.3.0",
"parseurl": "^1.3.2",
"sequelize": "^4.23.2",
"serve-favicon": "~2.4.5",
"statuses": "^1.4.0",
"unpipe": "^1.0.0"
}
}

MySQL安装

没啥好说的,需要MySQL官网文件
navicat112_premium_cs_x64可视化查看数据库
环境是win10,安装完后服务里会多出MySQL的服务,随系统启动

正式代码篇

测试项目,只为了入门,文件不分类 用到的文件就3个

  • ./bin/www
  • app.js
  • ./routes/user.js

www

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
/* 启动文件 */
var app = require('../app');
var debug = require('debug')('server:server');
var http = require('http');
// 监听端口号
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
var server = http.createServer(app);


server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

// 底下是监听到的错误输出之类的
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}

function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

app.js

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
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var ejs = require('ejs');
var users = require('./routes/users');
var app = express();
var router = express.Router();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('.html', ejs.__express);
app.set('view engine', 'html');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(express.static(path.join(__dirname, 'public')));

//跨域请求
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Access-Control-Allow-Credentials,Origin,X-Requested-With,Content-Type");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1');
res.header("Content-Type", "application/json;charset=utf-8");
res.header('Access-Control-Allow-Credentials', true);
next();
});

// 访问到的地址,首页为欢迎页
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express,Very Goood' });
});

// 将user中的路由和逻辑放到/users路由内
// 请求的地址就为/users/...
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});

// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});

module.exports = app;

user.js

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/* 用户登录以及数据库的逻辑 */
var express = require('express');
var app = express();
var mysql = require('mysql');
var session = require('express-session');
var Sequelize = require('sequelize');
var router = express.Router();
app.use(router)

/* SEQ-ORM */
// 连接数据库
var sequelize = new Sequelize('data', 'root', 'Root123', {
host: 'localhost',
dialect: 'mysql',
dialectOptions: {
charset: 'utf8mb4'
},
pool: {
max: 5, // 连接池中最大连接数量
min: 0, // 连接池中最小连接数量
idle: 10000 // 如果一个线程 10 秒钟内没有被使用过的话,那么就释放线程
},
operatorsAliases: false,
});
// 定义user模型
var User = sequelize.define('user', {
userName: {
type: Sequelize.STRING
},
passWord: {
type: Sequelize.STRING
},
hospital: {
type: Sequelize.STRING
}
}, {
// 不加会导致出现复数users未找到的错误
freezeTableName: true,
timestamps: false
});

// sequelize自动化给太多参数了,把不要的删掉
User.removeAttribute('id')
User.removeAttribute('createdAt')
User.removeAttribute('updatedAt')

// 定义病人查询模型
var patient = sequelize.define('patient', {
user: Sequelize.TEXT,
sex: Sequelize.STRING,
age: Sequelize.INTEGER,
num: Sequelize.INTEGER,
bed: Sequelize.INTEGER,
department: Sequelize.STRING,
}, {
// 不加会导致出现复数users未找到的错误
freezeTableName: true,
timestamps: false
});
patient.removeAttribute('id')
patient.removeAttribute('createdAt')
patient.removeAttribute('updatedAt')

// session代替cookie,防止cookie攻击
// 这里存放在内存中,正式的话需要存放于数据库
router.use(session({
// 加密字符串
secret: 'shopapp',
cookie: {
// 设置持续时间
maxAge: 60 * 1000 * 2,
secure: !true
},
saveUninitialized: true,
resave: true,
}));

// 通用页面
router.get('/', function (req, res, next) {
res.send('respond with a resource');
});
// 获取登录的用户名
router.get('/user', function (req, res, next) {
// 这里获取session中存放的用户名
if (req.session.user != null) {
res.json({
status: '0',
msg: '',
result: {
userName: req.session.user
},
})
} else {
res.json({
status: '1',
result: {
userName: ''
},
})
}
});
// 登录页面
router.post("/login", function (req, res, next) {
// 使用User数据库模型,查找用户名和面匹配的数据
User.all({
where: {
userName: req.body.user,
passWord: req.body.pw
}
}).then(function (doc) {
if (doc.length != 0) {
// 回调函数,这里返回的doc是个数组
console.log('数据' + JSON.stringify(doc))
// 将登录后的用户名存放在session中
req.session.user = doc[0].userName;
req.session.save();
res.json({
status: '0',
msg: '',
result: {
user: doc[0].userName,
hos: doc[0].hospital
}
})
} else {
res.json({
status: '1',
msg: ''
})
}
}).catch(function (err) {
console.log('错误' + err)
})
});
// 登出,删除session中登录的用户
router.post("/logout", function (req, res, next) {
req.session.destroy(function (err) {
if (err) {
console.log(err)
}
});
res.json({
status: "0",
msg: '',
result: ''
})
});

// 搜索病人(实际业务的例子)
router.post("/searchPatient", function (req, res, next) {
// 模糊查询需要的定义
const Op = Sequelize.Op;
patient.findAll({
where: {
// 以前是$or,后来改这个了
[Op.or]: [{
user: {
// 中文需要前后加%
[Op.like]: '%' + req.body.val + '%',
},
},
{
num: {
[Op.like]: req.body.val,
},
}
]
}
}).then(function (doc) {
if (doc.length != 0) {
console.log(doc)
var arr = []
// 将返回的数组添加到一起返回给前端
doc.forEach((i) => {
arr.push(i.dataValues)
})
res.json({
status: '1',
msg: arr
})
}
}).catch(function (err) {
console.log('错误' + err)
})
});

module.exports = router;

详情在注释里,有啥不知道的去搜索吧这里给的例子只是入手的参考