zvvq技术分享网

如何快速使用node.js进行web开发(nodejs写后端接口

作者:zvvq博客网
导读本篇文章主要介绍了快速使用node.js进行web开发详解,内容挺不错的,现在分享给大家,也给大家做个参考。 首先关于node.js的学习,这里推荐一本比较好的教程,nodejs web开发指南,该书

本篇文章主要介绍了快速使用node.js进行web开发详解,内容挺不错的,现在分享给大家,也给大家做个参考。 内容来自samhan666

首先关于node.js的学习,这里推荐一本比较好的教程,nodejs web开发指南,该书通俗易懂地将node.js语言特性讲解完之后,又从一个项目角度带领读者使用node.js学习web开发。相信这是一个比较好的学习模式和过程。由于这本书是2012年出的,书中的一个web教学项目是开发一个微博。从2012到现在,node.js及其生态环境发生了很大改变,所以关于该书的学习如果照着书本显然是过于陈旧的。到目前为止,node.js的web开发框架已经升级到了Express4.12.1,对于MongoDB的操作更多是使用mongoose这个对象模型,而不是之前mongoDB 官方提供的原生node.js的API,所以本文将基于nodejsV0.1033 + MongoDBV3.0.2+ Jade1.9.2 + mogooseV4.0.1来重构该书中的微博项目,这个组合也是目前最新的使用node.js进行web开发的常用组合之一,如果需要入门使用node.js进行web开发,正在学习nodejs web开发指南的和想快速了解node.js web开发模式的朋友,相信本文是有一定帮助意义的。

内容来自samhan666

1.express框架安装 zvvq.cn

1)在node命令行模式下输入以下命令

内容来自samhan

1

zvvq好,好zvvq

npm install -g express 内容来自zvvq

登录后复制

该命令在全局环境下安装express框架,在安装完这一步之后,并不能直接使用express命令来生成express项目,需要再安装一个express项目生成器,在express2.X的版本中是不需要的,express4.X版本之后将项目生成器和express本身分离了出来,如果不安装express-generator这个生成器就使用express命令来生成项目,会遇到报express不是内部或外部命令这个错误,这是需要注意的地方,nodejs web开发指南原书中是没有安装express-generator这一步的。

内容来自zvvq,别采集哟

2)安装express-generator

zvvq

1 本文来自zvvq

npm install -g express-generator

内容来自zvvq,别采集哟

登录后复制

3)生成一个项目

zvvq

1

本文来自zvvq

2

zvvq好,好zvvq

3

内容来自samhan666

4

zvvq好,好zvvq

cd .. zvvq.cn

mkdir microblog

本文来自zvvq

cd microblog

zvvq.cn

express micorblog 本文来自zvvq

登录后复制

这里随意在硬盘某个目录下创建一个microblog的文件夹,进入该文件夹,然后使用express microblog命令创建了一个microblog的express项目。 zvvq好,好zvvq

生成结构如下: zvvq.cn

内容来自samhan

其中app.js是项目入口文件,package.json是npm 包管理文件,bin文件夹里面的www.js放一些全局配置项以及命令行配置等。public 文件夹是用来存放项目静态文件目录如js,css以及图片,routes文件夹是用来存放路由监听的代码相关文件。views文件夹用来存放模板文件,这里需要注意的是express4.X使用jade作为项目的默认模板引擎,而在原书中是使用ejs作为模板引擎的,所以这里默认生成的是jade文件。无可否认ejs是要简单些,但是原理都是一样的,我们使用jade作为开发的模板引擎。

内容来自zvvq

4)启动项目并查看 内容来自zvvq,别采集哟

1 zvvq.cn

2 内容来自zvvq,别采集哟

3 zvvq.cn

cd microblog 内容来自zvvq

npm install 内容来自zvvq

npm start copyright zvvq

登录后复制

进入到microblog文件夹,安装项目所需相关模块(根据pacakge.json文件),然后启动项目,这时候打开浏览器查看项目输入地址localhost:3000,结果如下说明一切正常,

内容来自zvvq,别采集哟

zvvq好,好zvvq

到目前为止,我们已经拥有了一个在浏览器中运行的web项目雏形。下面进行开发,原书中的微博项目的主要功能是用户能够注册登录,权限控制并让用户发布微博在用户个人主页和项目首页分别显示,这些功能完整版代码会提供,由于篇幅原因,这里以用户注册登录模块来说明如何进行一个完整流程的web开发。

内容来自zvvq,别采集哟

2.页面布局 内容来自zvvq,别采集哟

依照web开发流程,我们首先来构建一个项目主页,项目主页是由布局文件layout.jade和内容文件index.jade组成,关于的jade的学习,这里提供两个地址,对于以前使用过类似模板引擎如smarty,razor等的,可以看看文档就能够上手做了,基本原理都是大同小异。

内容来自zvvq

打开views文件,将layout.jade文件代码改写如下: zvvq

1

内容来自zvvq,别采集哟

2

内容来自samhan

3

内容来自zvvq,别采集哟

4

zvvq

5

本文来自zvvq

6 copyright zvvq

7 zvvq好,好zvvq

8

copyright zvvq

9 内容来自zvvq,别采集哟

10

内容来自samhan666

11

内容来自zvvq

12 zvvq好,好zvvq

13 内容来自zvvq

14 copyright zvvq

15 内容来自zvvq

16 内容来自zvvq,别采集哟

17

zvvq.cn

18

zvvq.cn

19

zvvq.cn

20 内容来自zvvq,别采集哟

21

内容来自samhan666

22

本文来自zvvq

23

内容来自zvvq,别采集哟

doctype html zvvq

html copyright zvvq

head 内容来自zvvq,别采集哟

title= title copyright zvvq

link(rel='stylesheet', href='/stylesheets/style.css')

zvvq.cn

body 内容来自zvvq,别采集哟

nav.header

zvvq.cn

ul.list

copyright zvvq

li.logo zvvq

a(href='/') Microblog

zvvq

li 内容来自samhan666

a(href='/') 首页

本文来自zvvq

li zvvq.cn

a(href='/login') 登录 内容来自zvvq,别采集哟

li copyright zvvq

a(href='/reg') 注册 内容来自samhan

p.container

zvvq.cn

block content 内容来自zvvq,别采集哟

hr

内容来自samhan

footer.footer

本文来自zvvq

p copyright zvvq

a(href='http://myzhibie.coding.io') myzhibie 本文来自zvvq

| @2015 zvvq好,好zvvq

登录后复制

需要注意父级元素和子元素的换行之间缩进,jade是利用缩进来区别代码层级的。 zvvq好,好zvvq

首页内容文件index.jade zvvq.cn

1 内容来自zvvq

2

zvvq好,好zvvq

3

内容来自samhan666

4

zvvq.cn

5 内容来自zvvq

6

zvvq

7 zvvq

8 zvvq好,好zvvq

9 内容来自zvvq,别采集哟

10

内容来自samhan

11

zvvq.cn

12

内容来自samhan

13 内容来自samhan

14

本文来自zvvq

15 zvvq.cn

16 内容来自zvvq

17

zvvq

18

zvvq好,好zvvq

19 zvvq

20 内容来自samhan

21 copyright zvvq

22 copyright zvvq

23 内容来自zvvq,别采集哟

24 zvvq

25

copyright zvvq

26 zvvq

27

内容来自samhan666

extends layout copyright zvvq

block content 内容来自zvvq,别采集哟

main.main 内容来自zvvq

section.intro

zvvq.cn

if message

本文来自zvvq

h3.indexmes #{message}

内容来自zvvq

//如果用户登录或者注册成功并且没有在登录状态下点击注册或者登录

本文来自zvvq

if success&&user 内容来自samhan

h1.welcome #{success},欢迎 #{user} 来到 Microblog zvvq好,好zvvq

else if !success&&user

内容来自samhan666

h1.welcome 欢迎 #{user} 来到 Microblog

内容来自samhan666

else

内容来自samhan

h1.welcome 欢迎来到 Microblog copyright zvvq

h3.tech Microblog是一个基于Node.js,使用express4.12.1,jade1.9.2以及MongoDB搭建起来的微博系统,是对Node.js开发指南一书中教学项目的重构。

zvvq.cn

p.btnlist 内容来自zvvq,别采集哟

if user zvvq.cn

a.login(href='/logout') 退出

copyright zvvq

a.userlink(href='/users/#{user}') 发表文章

zvvq好,好zvvq

else

内容来自zvvq,别采集哟

a.login(href='/login') 登录

内容来自samhan666

a.register(href='/reg') 立即注册

copyright zvvq

section.show

内容来自zvvq

each val in posts

copyright zvvq

article.col copyright zvvq

h3.author #{val.user}说 内容来自zvvq,别采集哟

p zvvq好,好zvvq

| #{val.post}

内容来自zvvq,别采集哟

登录后复制

首页内容是继承了模板文件layout.jade.原书中使用的bootstrap来构建页面的css布局和样式,这里我自己手写了一个仿bootstrap风格的布局样式,没有应用bootstrap,style.css文件如下: 内容来自samhan

1 本文来自zvvq

2

内容来自zvvq,别采集哟

3

zvvq好,好zvvq

4

copyright zvvq

5 zvvq.cn

6 zvvq好,好zvvq

7

内容来自samhan

8

内容来自zvvq

9

zvvq.cn

10

内容来自samhan

11 zvvq

12 zvvq好,好zvvq

13

zvvq好,好zvvq

14

内容来自zvvq

15

zvvq.cn

16 zvvq好,好zvvq

17

zvvq.cn

18 内容来自samhan666

19 内容来自zvvq,别采集哟

20 zvvq好,好zvvq

21 zvvq.cn

22

内容来自zvvq

23

内容来自zvvq

24 内容来自zvvq,别采集哟

25

内容来自samhan666

26

zvvq好,好zvvq

27

zvvq.cn

28 zvvq好,好zvvq

29

zvvq好,好zvvq

30 内容来自samhan

31 copyright zvvq

32 zvvq

33

内容来自samhan

34

本文来自zvvq

35 内容来自samhan666

36 zvvq

37 内容来自samhan666

38 内容来自zvvq

39

zvvq.cn

40

内容来自samhan

41 copyright zvvq

42 zvvq.cn

43

内容来自zvvq

44 zvvq.cn

45 copyright zvvq

46 内容来自samhan

47

内容来自samhan

48 内容来自samhan

49 内容来自samhan666

50

zvvq.cn

51

内容来自zvvq,别采集哟

52

zvvq

53 内容来自samhan666

54 zvvq好,好zvvq

55

copyright zvvq

56

内容来自zvvq,别采集哟

57 内容来自zvvq,别采集哟

58

zvvq好,好zvvq

59

zvvq好,好zvvq

60

内容来自samhan

61

内容来自samhan666

62

zvvq

63 zvvq.cn

64 内容来自zvvq

65

zvvq.cn

66 zvvq.cn

67

zvvq.cn

68 copyright zvvq

69

zvvq.cn

70 内容来自samhan

71 zvvq好,好zvvq

72

内容来自samhan666

73

内容来自zvvq,别采集哟

74

zvvq好,好zvvq

75

zvvq好,好zvvq

76 内容来自samhan

77 copyright zvvq

78

copyright zvvq

79

zvvq好,好zvvq

80

内容来自zvvq,别采集哟

81 zvvq.cn

82

内容来自zvvq,别采集哟

83

内容来自samhan

84

zvvq

85 内容来自samhan666

86 内容来自samhan666

87

内容来自zvvq

88

zvvq好,好zvvq

89 zvvq好,好zvvq

90

zvvq.cn

91 内容来自zvvq

92

内容来自zvvq

93 内容来自zvvq,别采集哟

94

zvvq

95 内容来自zvvq

96

copyright zvvq

97 zvvq.cn

98

本文来自zvvq

99

内容来自zvvq,别采集哟

100

内容来自zvvq,别采集哟

101

内容来自zvvq,别采集哟

102

内容来自samhan

103 内容来自samhan

104

内容来自samhan

105

zvvq.cn

106

内容来自samhan

107 本文来自zvvq

108 内容来自zvvq

109

copyright zvvq

110

本文来自zvvq

111 内容来自zvvq,别采集哟

112

内容来自zvvq,别采集哟

113

内容来自samhan666

114 内容来自samhan666

115 zvvq

116 zvvq

117

zvvq.cn

118 zvvq好,好zvvq

119 内容来自samhan666

120

zvvq.cn

121 zvvq.cn

122

内容来自zvvq,别采集哟

123 内容来自zvvq

124 zvvq

125 本文来自zvvq

126

zvvq好,好zvvq

127 内容来自samhan666

128

zvvq.cn

129 内容来自zvvq

130

zvvq

131

zvvq

132 zvvq.cn

133 内容来自samhan666

134 内容来自samhan

135

内容来自zvvq,别采集哟

136 内容来自samhan666

137 zvvq好,好zvvq

138 copyright zvvq

139

zvvq好,好zvvq

140

内容来自zvvq

141

zvvq

142 内容来自zvvq,别采集哟

143 内容来自samhan

144

copyright zvvq

145

内容来自samhan666

146 内容来自zvvq,别采集哟

147

内容来自samhan666

148 内容来自zvvq,别采集哟

149

内容来自zvvq

150

zvvq好,好zvvq

151 内容来自zvvq,别采集哟

152 内容来自zvvq,别采集哟

153

zvvq

154 copyright zvvq

155

copyright zvvq

156

zvvq好,好zvvq

157 内容来自samhan666

158

zvvq

159 本文来自zvvq

160

zvvq

161

zvvq好,好zvvq

162

copyright zvvq

163 copyright zvvq

164

copyright zvvq

165

内容来自zvvq

166 内容来自samhan666

167 zvvq

168

本文来自zvvq

169 zvvq

170 zvvq.cn

171 内容来自zvvq

172

内容来自samhan666

173

内容来自samhan666

174

内容来自samhan

175 内容来自zvvq,别采集哟

176 zvvq

177

内容来自zvvq,别采集哟

178

zvvq.cn

179 内容来自samhan666

180 zvvq好,好zvvq

181

zvvq好,好zvvq

182 内容来自zvvq,别采集哟

183 zvvq.cn

184

copyright zvvq

185 内容来自samhan666

186 内容来自zvvq,别采集哟

187 zvvq好,好zvvq

188 copyright zvvq

189

内容来自samhan666

190

zvvq好,好zvvq

191 内容来自samhan666

192

内容来自zvvq,别采集哟

193 copyright zvvq

194

zvvq好,好zvvq

195

内容来自zvvq

196 内容来自samhan666

197 zvvq

198

本文来自zvvq

199 copyright zvvq

200 zvvq好,好zvvq

201

zvvq.cn

202

zvvq好,好zvvq

203

内容来自samhan666

204

内容来自samhan

205 zvvq好,好zvvq

206

zvvq好,好zvvq

207 内容来自zvvq,别采集哟

208

zvvq.cn

209

内容来自zvvq,别采集哟

210

zvvq

211

zvvq

212 内容来自samhan666

213

本文来自zvvq

214

本文来自zvvq

215 本文来自zvvq

216 zvvq好,好zvvq

217

内容来自zvvq,别采集哟

218

copyright zvvq

219 内容来自zvvq,别采集哟

220

zvvq.cn

221

内容来自zvvq,别采集哟

222

本文来自zvvq

223 内容来自samhan

224 本文来自zvvq

225 内容来自samhan

226 zvvq.cn

227 本文来自zvvq

228 内容来自samhan666

229

内容来自samhan666

230 内容来自samhan

231 本文来自zvvq

232

内容来自samhan666

233

copyright zvvq

234 zvvq

235 zvvq.cn

236 zvvq好,好zvvq

237 内容来自zvvq,别采集哟

238

内容来自zvvq

239

内容来自samhan666

240 内容来自zvvq

241

内容来自zvvq,别采集哟

242 zvvq

243

copyright zvvq

244

内容来自zvvq

245 内容来自samhan

246 内容来自zvvq,别采集哟

247

内容来自zvvq

248 copyright zvvq

249

内容来自samhan

250 内容来自zvvq

251

zvvq

252 内容来自zvvq,别采集哟

253

copyright zvvq

254 内容来自samhan

255 内容来自samhan

256 内容来自zvvq,别采集哟

257

内容来自zvvq,别采集哟

258 本文来自zvvq

259

zvvq.cn

260

zvvq

261 内容来自zvvq

262

zvvq好,好zvvq

263

内容来自samhan

264 zvvq好,好zvvq

265

zvvq.cn

266 内容来自zvvq,别采集哟

267 copyright zvvq

268 内容来自samhan666

269

zvvq

270 内容来自zvvq,别采集哟

body { zvvq

padding: 50px; 内容来自zvvq,别采集哟

font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 本文来自zvvq

} zvvq好,好zvvq

html,body,ul,p,hr,h3{

内容来自samhan666

margin:0;

本文来自zvvq

padding: 0;

本文来自zvvq

}

zvvq好,好zvvq

a { 内容来自zvvq

color: #00B7FF; 内容来自samhan

}

zvvq好,好zvvq

.header{ zvvq.cn

background:#337aB7; 内容来自zvvq

width: 100%; 内容来自zvvq

height: 60px;

本文来自zvvq

color: #fff; zvvq好,好zvvq

font-size: 22px;

zvvq.cn

overflow: hidden; 内容来自samhan666

} zvvq好,好zvvq

.list{ zvvq好,好zvvq

line-height: 60px;

zvvq好,好zvvq

}

内容来自samhan

.navigation{

内容来自samhan

overflow: hidden;

copyright zvvq

} 内容来自samhan

.list li{ 本文来自zvvq

list-style: none;

内容来自samhan666

float: left; 内容来自zvvq

display: inline-block;

内容来自zvvq,别采集哟

margin-left: 20px;

本文来自zvvq

margin-right: 20px; 内容来自zvvq

} 内容来自zvvq

.list li a{ copyright zvvq

text-decoration: none; 内容来自zvvq

color: #fff; 内容来自samhan

} 内容来自samhan

.list li a:hover{

zvvq好,好zvvq

}

内容来自samhan666

.list li:not(:first-child) a:hover{ zvvq.cn

font-size: 26px; 内容来自samhan

color: #F5F5F5;

本文来自zvvq

} 内容来自samhan666

.logo{

copyright zvvq

font-size: 26px; zvvq

font-weight: 700; zvvq

} zvvq

.container{ 内容来自zvvq

min-height: 500px; zvvq好,好zvvq

text-align: center;

copyright zvvq

width: 100%;

zvvq

} 本文来自zvvq

.footer{ copyright zvvq

width: 100%; 内容来自zvvq,别采集哟

height: 50px; 内容来自samhan666

font-size: 22px;

zvvq好,好zvvq

background:#F5F5F5 ; 内容来自zvvq

line-height: 50px; 本文来自zvvq

}

zvvq.cn

.footer a{

内容来自zvvq

color:#337aB7;

zvvq.cn

text-decoration: none; 内容来自samhan666

} 内容来自samhan

.main{ 内容来自samhan

color: #000000; zvvq好,好zvvq

width: 96%; 内容来自zvvq,别采集哟

margin: 30px auto; 内容来自zvvq,别采集哟

} 内容来自zvvq,别采集哟

.intro{ zvvq.cn

width: 100%;

zvvq.cn

margin:0 auto;

内容来自samhan

border-radius: 5px;

本文来自zvvq

height: 300px;

内容来自samhan

background:#F5F5F5 ;

内容来自zvvq

}

内容来自zvvq,别采集哟

.userintro{ zvvq

width: 100%;

内容来自zvvq

margin:0 auto; 内容来自samhan666

border-radius: 5px; 本文来自zvvq

height: 200px; 内容来自samhan666

background:#F5F5F5 ; 内容来自samhan

}

zvvq好,好zvvq

.welcome{

本文来自zvvq

padding-top: 50px;

本文来自zvvq

padding-left:50px; copyright zvvq

font-size: 50px;

zvvq好,好zvvq

text-align: left;

内容来自samhan666

padding-bottom: 0; 本文来自zvvq

margin: 0;

内容来自samhan

} zvvq好,好zvvq

.tech{ zvvq好,好zvvq

text-align: left;

内容来自zvvq

padding-left:50px;

本文来自zvvq

margin: 0; 内容来自zvvq

}

内容来自samhan

.show{ 内容来自samhan666

overflow: hidden;

zvvq

width: 100%;

zvvq.cn

} copyright zvvq

.show li{

本文来自zvvq

text-align: left; 内容来自zvvq

font-size: 18px;

本文来自zvvq

}

本文来自zvvq

.col{ 内容来自zvvq

display: inline-block;

内容来自zvvq

float: left;

copyright zvvq

width: 32%; 内容来自zvvq,别采集哟

height: 100px;

内容来自samhan666

overflow: hidden;

copyright zvvq

padding-right: 20px;

zvvq好,好zvvq

text-align: left; zvvq.cn

text-overflow: ellipsis; zvvq.cn

}

copyright zvvq

.author{

copyright zvvq

margin-top: 10px; 内容来自samhan666

margin-bottom: 3px; 内容来自samhan

}

内容来自samhan666

.btnlist{

内容来自samhan666

padding-left: 50px; copyright zvvq

text-align: left; zvvq

}

本文来自zvvq

.login{ zvvq.cn

display: inline-block; 内容来自samhan666

padding-left: 15px; copyright zvvq

padding-right: 15px;

本文来自zvvq

height: 38px; zvvq好,好zvvq

line-height: 40px; 内容来自zvvq,别采集哟

background: -webkit-gradient(linear, left top, left bottom, from(#0068A6), to(#337aB7));

copyright zvvq

color: #fff; 内容来自zvvq,别采集哟

text-align: center; 内容来自samhan666

border-radius: 5px; zvvq.cn

font-size: 20px;

zvvq好,好zvvq

font-weight: 600; 内容来自zvvq,别采集哟

border: 1px solid #ccc; zvvq.cn

text-decoration: none; copyright zvvq

margin-right: 10px;

copyright zvvq

} 内容来自samhan

.register{ copyright zvvq

display: inline-block; 内容来自zvvq,别采集哟

padding-left: 15px;

本文来自zvvq

padding-right: 15px; copyright zvvq

height: 38px; 本文来自zvvq

line-height: 40px;

本文来自zvvq

background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#F5F5F5)); 本文来自zvvq

color: #000;

内容来自samhan

text-align: center; zvvq

border-radius: 5px; zvvq好,好zvvq

font-size: 20px;

本文来自zvvq

font-weight: 600; 内容来自zvvq

border: 1px solid #ccc; 内容来自samhan666

text-decoration: none; 内容来自zvvq,别采集哟

}

内容来自samhan666

.field{ zvvq

margin-top: 20px; 内容来自samhan

margin-left: 50px; 内容来自samhan

text-align: left;

内容来自samhan

margin-bottom: 20px; 内容来自samhan

border:none;

内容来自samhan

border-bottom: 1px solid #ccc;

copyright zvvq

}

内容来自samhan

.label{ 内容来自samhan666

font-size: 18px; copyright zvvq

font-weight: 600; zvvq.cn

line-height: 100%;

内容来自samhan666

display: inline-block; 内容来自samhan

width: 10%; zvvq好,好zvvq

vertical-align: middle; 内容来自samhan666

text-align: right;

zvvq好,好zvvq

padding-right: 10px; zvvq

}

copyright zvvq

.regheader{ 内容来自zvvq,别采集哟

text-align: left; 内容来自samhan666

font-size: 24px;

zvvq

font-weight: 600;

内容来自zvvq,别采集哟

}

本文来自zvvq

.regform{

zvvq.cn

text-align: left; 内容来自zvvq,别采集哟

padding-left: 100px;

内容来自samhan

margin-bottom: 20px;

内容来自zvvq

} zvvq

.regform input[type='text'],input[type='password']{ 内容来自samhan

width: 200px; zvvq

height: 20px; 内容来自zvvq,别采集哟

} 内容来自samhan

.regform input[type='submit']{

内容来自samhan666

width: 120px;

内容来自zvvq,别采集哟

height: 30px;

zvvq.cn

color: #fff; 内容来自samhan666

background:-webkit-gradient(linear, left top, left bottom, from(#0068A6), to(#337aB7));

copyright zvvq

border-radius: 5px; zvvq.cn

font-size: 20px;

内容来自zvvq,别采集哟

} copyright zvvq

.item{ zvvq好,好zvvq

margin:20px;

zvvq.cn

width: 100%;

zvvq好,好zvvq

}

内容来自samhan666

.mess{ copyright zvvq

font-size: 18px;

本文来自zvvq

color: #E73C3C; zvvq.cn

background: #F2DEDE;

内容来自samhan666

border-radius: 5px; 内容来自samhan

width: 300px;

zvvq.cn

text-align: center;

zvvq.cn

margin-left: 100px; zvvq

}

zvvq.cn

.indexmes{ copyright zvvq

height: 30px;

zvvq.cn

line-height: 30px; 本文来自zvvq

background: #F2DEDE; zvvq.cn

color: #E73C3C; 内容来自zvvq,别采集哟

}

copyright zvvq

.article{

copyright zvvq

width: 60%;

zvvq.cn

height: 30px;

本文来自zvvq

border-radius: 3px; zvvq好,好zvvq

border: 1px solid #A3C732; 内容来自samhan

margin-top: 5px; 内容来自zvvq

font-size: 20px; copyright zvvq

}

内容来自samhan666

.submit{ zvvq

height: 40px; 内容来自zvvq,别采集哟

vertical-align: middle; 内容来自samhan666

padding: 0; copyright zvvq

margin-top: -5px;

zvvq.cn

margin-left: 5px;

zvvq好,好zvvq

width: 80px; 内容来自samhan666

background: #A3c732; zvvq.cn

font-size: 20px; zvvq.cn

border: none; 内容来自samhan

border-radius: 5px; zvvq.cn

color: #fff; zvvq.cn

} 本文来自zvvq

.submitform{ zvvq.cn

margin-top: 25px; zvvq好,好zvvq

margin-left: -10px; 内容来自zvvq,别采集哟

} 本文来自zvvq

.userlink{ 内容来自zvvq,别采集哟

display: inline-block;

zvvq好,好zvvq

text-decoration: none;

zvvq

line-height: 38px;

zvvq

height: 38px;

内容来自zvvq

vertical-align: middle;

内容来自samhan666

padding: 0;

copyright zvvq

margin-top: -8px; copyright zvvq

margin-left: 5px; zvvq.cn

width: 90px; copyright zvvq

text-align: center; copyright zvvq

background: #A3c732;

本文来自zvvq

font-size: 20px;

内容来自samhan

font-weight: 600;

zvvq好,好zvvq

border-radius: 5px; zvvq

color: #fff; 内容来自zvvq

border: 1px solid #ccc; 内容来自zvvq

}

本文来自zvvq

.usertitle{ copyright zvvq

text-align: left;

内容来自zvvq

padding-top: 5px;

zvvq好,好zvvq

padding-bottom: 0; 内容来自samhan

padding-left: 5px; zvvq好,好zvvq

margin-bottom: 8px;

copyright zvvq

} 内容来自samhan

.usersuccess{ zvvq好,好zvvq

height: 30px; zvvq.cn

background: #DFF0D8;

zvvq

line-height: 30px; zvvq

color: #3C7668; copyright zvvq

} 内容来自zvvq

登录后复制

这个css文件是项目中所有的css全部包含在这里,所以比较庞大。到目前为止,可以查看首页效果如下: 内容来自zvvq

内容来自zvvq

首页中的数据都是之前自己测试过程中加入的,这里主要为了查看首页效果,可以忽略这些数据。

内容来自samhan

由于这里要演示用户注册登录模块,用户注册模块的模板文件reg.jade如下: zvvq.cn

1 内容来自zvvq

2 zvvq.cn

3

内容来自zvvq,别采集哟

4

zvvq.cn

5 zvvq

6

zvvq好,好zvvq

7

内容来自samhan666

8

本文来自zvvq

9 内容来自zvvq,别采集哟

10

内容来自samhan666

11

zvvq好,好zvvq

12 zvvq.cn

13 内容来自zvvq,别采集哟

14

本文来自zvvq

15

内容来自samhan

16

zvvq好,好zvvq

17 本文来自zvvq

extends layout zvvq

block content copyright zvvq

h3.field.regheader #{title} zvvq好,好zvvq

form.regform(method='post')

zvvq

p.mess #{message} copyright zvvq

p.item 本文来自zvvq

label.label(for='username') 用户名

内容来自zvvq

input(type='text',placeholder='输入注册用户名',id='username',name='username')

zvvq

p.item

内容来自zvvq

label.label(for='password') 用户密码

内容来自samhan

input(type='password',placeholder='用户密码',id='password',name='password') 本文来自zvvq

p.item 内容来自zvvq

label.label(for='passwordconf') 重复密码 内容来自samhan

input(type='password',placeholder='重复密码',id='passwordconf',name='passwordconf') zvvq好,好zvvq

p.item

copyright zvvq

label.label

内容来自samhan666

input(type='submit' id='sub',name='sub' value='注册')

本文来自zvvq

登录后复制

用户登陆模板login.jade如下: 内容来自samhan

1

内容来自samhan666

2

zvvq

3 copyright zvvq

4 zvvq.cn

5

内容来自zvvq,别采集哟

6

zvvq好,好zvvq

7

copyright zvvq

8

内容来自zvvq

9

内容来自samhan666

10

copyright zvvq

11 zvvq好,好zvvq

12

zvvq好,好zvvq

13

本文来自zvvq

14

内容来自zvvq

extends layout 本文来自zvvq

block content

zvvq

h3.field.regheader #{title} 内容来自samhan666

form.regform(method='post')

本文来自zvvq

p.mess #{message} zvvq.cn

p.item

内容来自samhan

label.label(for='username') 用户名

zvvq.cn

input(type='text',placeholder='输入登陆用户名',id='username',name='username')

内容来自zvvq,别采集哟

p.item

zvvq

label.label(for='password') 用户密码

copyright zvvq

input(type='password',placeholder='用户密码',id='password',name='password') zvvq好,好zvvq

p.item zvvq

label.label

zvvq

input(type='submit' id='sub',name='sub' value='登陆')

内容来自samhan666

登录后复制

最终用户注册效果如下:

内容来自zvvq,别采集哟

内容来自zvvq,别采集哟

用户登录模块和这个效果相仿,就不查看了,少了一个重复密码的input而已。 内容来自zvvq

下面我们需要编写用户注册的逻辑,在编写用户注册逻辑的前,用户数据需要持久化,所以首先要安装MongoDB数据库在自己的机器上.

内容来自samhan

MongoDB这种nosql类型的数据库,非常适合用户存储JSON对象类型的数据,有了mongoDB,就可以免去数据库表设计部分的工作,对比以前使用的mysql,sqlserver以及oracle还是非常方便的。关于mongoDB数据库的熟悉和学习,推荐其官网,官网详细介绍了该数据库的一切。英文不好可以去中文社区。同时为了使用nodejs来操作mongoDB数据库,我们使用mongoose这个对象模型,它是将mongoDB中的一个集合映射为nodejs中的一个model,然后在该model上提供操作这个集合的一些方法,使用它就可以避免我们自己利用nodejs提供的原生操作mongoDB数据库的语法去手写数据库CURD的方法,大大见晒了工作量,提高了开发效率。关于mongoose的学习,推荐去其官网,里面详述了它的安装,使用以及API调用情况。 zvvq.cn

解决了mongoDB安装和操作问题,我们来对数据库操作的model类,首先在项目路径下建立一个db.js文件,用来连接数据库并对数据库进行全局配置,如下 本文来自zvvq

db.js zvvq.cn

1 内容来自samhan

2

内容来自samhan666

3

内容来自samhan666

4 内容来自zvvq,别采集哟

5 内容来自zvvq,别采集哟

6

内容来自zvvq,别采集哟

7

zvvq.cn

8

内容来自zvvq,别采集哟

var settings=require("./settings"); 内容来自zvvq

var mongoose=require('mongoose'); copyright zvvq

mongoose.connect("mongodb://"+settings.ip+"/"+settings.db); 本文来自zvvq

var db=mongoose.connection;

zvvq好,好zvvq

module.exports={

本文来自zvvq

"dbCon":db,

zvvq.cn

"mongoose":mongoose

内容来自samhan666

};

本文来自zvvq

登录后复制

这里首先加载了配置文件settings.js文件,为了数据库便于灵活修改,我们将某些信息存储在配置文件中。然后加在了之前安装的mongoose模块,然后调用该模块的connect方法来连接我们配置的数据库,然后将连接以对象的形式返回供外部调用。

本文来自zvvq

settings.js 内容来自zvvq

1 copyright zvvq

2 内容来自samhan

3

内容来自zvvq,别采集哟

4

copyright zvvq

5 内容来自zvvq,别采集哟

module.exports={

zvvq好,好zvvq

"ip":"localhost", copyright zvvq

"db":"microblog",

zvvq.cn

"host":27071 内容来自samhan666

};

内容来自samhan

登录后复制

MongoDB的默认端口是27071,一般可以使用默认端口即可,数据库连接大时候可以不指定端口,数据库名为microblog. 本文来自zvvq

然后以db.js返回的数据库连接对象为基础,我们在项目根目录下创建一个models文件夹,用来存放数据模型。创建一个user.js映射我们数据库中的user集合(可以理解为user表),代码如下:

zvvq.cn

1

zvvq.cn

2 内容来自zvvq,别采集哟

3

zvvq好,好zvvq

4

内容来自zvvq,别采集哟

5 本文来自zvvq

6 内容来自zvvq

7

copyright zvvq

var mongoose=require('../db').mongoose;

内容来自zvvq

var schema=new mongoose.Schema({

copyright zvvq

name:'string', 内容来自zvvq

password:'string' 内容来自zvvq,别采集哟

});

zvvq

var User=mongoose.model('User',schema); 内容来自zvvq,别采集哟

module.exports=User; 内容来自samhan666

登录后复制

这里首先获得db.js中定义的连接对象,并以该对象为基础构造一个Schema(架构),mogoose操作数据库是以架构为基础的,类似于我们其他ORM模型中属性和方法的定义。这里我们定义了一个架构,拥有两个属性,name和password,都是string类型,对应用户的用户名和密码。然后利用该架构去创建一个model,该model上定义了对数据集合的增删改查等方法,不用我们自己再去定义和编写其他代码。在原书中这一节是利用node.js操作MongoDB数据库的原生API去定义了一个user对象,然后在user对象上自定义了一些CRUD的方法。可以看出,直接使用Mongoose可以大大减少开发量并且拥有更好的效率和性能。 zvvq好,好zvvq

到目前为止,我们已经有了界面(view),数据模型(model),就差逻辑代码(controller)没有编写了。在编写逻辑代码之前需要先说下express框架的特点以及它的整体运行方式。由于本人使用过一些类似的如Asp.net mvc,Yii以及thinkphp等MVC框架,使用express之后最大的感觉是这个框架够轻量级,尤其是express4.X之后,它仅仅保留了静态文件路径映射模块作为该框架本身的内置模块,其他的功能都以中间件的形式采用require(modulename)进行引入,只有引入后才能够使用该模块提供的功能。

copyright zvvq

express的工作原理是客户端发送一个request,express接到该请求,可以将它进行处理之后传递给其他中间件进行处理,最终处理完成之后,采用respond.end或者response.render进行页面渲染或响应,进行页面渲染的时候,采用参数传递页面需要的数据给对应模板引擎,模板引擎收到数据然后按照自己的语法进行替换生成对应的html,最终返回给浏览器进行渲染。 内容来自samhan

在express中,最关键的部分就是路有机制,我们所有基于请求做出的响应都是对该路由进行监听捕获的结果。举个例子,如果我们请求一个路径为http://localhost:3000/user,那么必须在routes文件夹下面的路径监听(暂且叫做监听吧)的js文件中编写对该请求的响应代码,诸如app.post(/user,function(...){...})之类的代码,如果不存在这样的代码,就会报一个404错误,因为请求没有得到响应,express实例不知道怎么去响应这个请求。以上就是express大致的原理和工作流程,对于它的学习,推荐去express官网直接去看文档,讲的很详细。

内容来自samhan666

现在回到用户注册模块,我们注册用户常见的做法是注册成功之后就默认用户已经登录,直接跳转到欢迎登陆界面。在这里我们需要将用户数据在注册成功之后保存在session中,express框架对于session的支持是通过中间件express-session来的,使用方式依然是在npm 下安装,然后在项目主文件中使用require加载,最后调用其提供的API,为了使用session,必须先安装cookie的支持,这里利用cookie-parser这个中间件来为express框架提供cookie支持,它的具体使用方式可以去上面提供的地址自行查看。对于session,我们常见框架的做法是在服务器端将其存放到文件当中,由于这里我们有了MongoDB数据库,更理想的状态是将它存在数据库中,这样可以更灵活去控制。使用connect-mongo中间件可以将session存储到mongoDB中,具体使用方式可按地址查看。

zvvq好,好zvvq

上述概念明确之后,我们在项目根目录下的app.js(项目入口文件)中加载我们需要的中间件模块和自定义的模块如下: zvvq好,好zvvq

app.js模块加载代码: copyright zvvq

1 copyright zvvq

2 内容来自zvvq

3

内容来自zvvq

4 zvvq.cn

5

内容来自zvvq

6 copyright zvvq

7 内容来自samhan

8 copyright zvvq

9 copyright zvvq

10 内容来自zvvq,别采集哟

11

copyright zvvq

12 copyright zvvq

13 zvvq.cn

14 zvvq.cn

15 zvvq

16 zvvq

17

内容来自zvvq

18 copyright zvvq

19

内容来自samhan666

20 内容来自zvvq

21

zvvq好,好zvvq

22 本文来自zvvq

23 内容来自samhan

24 zvvq好,好zvvq

25 内容来自zvvq,别采集哟

26

zvvq

27 内容来自zvvq,别采集哟

28 内容来自samhan666

29

copyright zvvq

30

copyright zvvq

31

copyright zvvq

32 zvvq好,好zvvq

33 zvvq好,好zvvq

34

内容来自samhan

var express = require('express'); 内容来自zvvq,别采集哟

var path = require('path'); 内容来自zvvq

var favicon = require('serve-favicon');

内容来自zvvq,别采集哟

var logger = require('morgan'); zvvq好,好zvvq

var cookieParser = require('cookie-parser');

zvvq

var bodyParser = require('body-parser');

copyright zvvq

var routes = require('./routes/index');

zvvq好,好zvvq

var users = require('./routes/users'); zvvq

var session = require("express-session");

内容来自zvvq

var MongoStore=require('connect-mongo')(session); 内容来自zvvq

var db = require('./db');

zvvq

var app = express();

zvvq

// view engine setup zvvq

app.set('views', path.join(__dirname, 'views'));

内容来自samhan

app.set('view engine', 'jade'); zvvq

// uncomment after placing your favicon in /public 本文来自zvvq

//app.use(favicon(__dirname + '/public/favicon.ico')); 本文来自zvvq

app.use(logger('dev')); copyright zvvq

app.use(bodyParser.json());

内容来自zvvq,别采集哟

app.use(bodyParser.urlencoded({ extended: false })); zvvq

app.use(cookieParser());

zvvq.cn

app.use(express.static(path.join(__dirname, 'public'))); zvvq.cn

app.use(session({

内容来自zvvq

secret:"myzhibie",

内容来自zvvq,别采集哟

store:new MongoStore({

内容来自zvvq

mongooseConnection:db.dbCon zvvq好,好zvvq

})

内容来自samhan

}));

内容来自zvvq

app.use('/', routes);

zvvq

app.use('/users', users);

本文来自zvvq

登录后复制

上述代码就是加载各个中间件模块并采用app.use来load这个模块,其中上述代码的最后一指定了将session存储在MongoDB数据库中,secret属性是对session的签名,通常是一个字符串,这是必选项,如果不写, 内容来自zvvq

是无法完成将session存储进入数据库的,关于该功能的更详细介绍请查看文档,最后两句app.use(/,routes)和app.use(/users,users)代表对于这两个路由的访问处理代码我们封装在了routes和users模块中,er这两个模块都在routes文件夹下面。 本文来自zvvq

完成了模块引入加载和一些基本的设置,现在来编写用户注册的逻辑代码,上面说到对于路径/的访问处理在routes模块中,这个模块指的就是routes文件夹下面的index.js,部分代码如下: 本文来自zvvq

1

zvvq好,好zvvq

2

zvvq好,好zvvq

3 内容来自zvvq,别采集哟

4 内容来自zvvq,别采集哟

5

内容来自zvvq,别采集哟

6 内容来自samhan

7

copyright zvvq

8

内容来自samhan666

9

内容来自samhan

10

copyright zvvq

11

内容来自samhan

12

zvvq

13 zvvq.cn

14

内容来自zvvq

15

内容来自zvvq

16

本文来自zvvq

17 内容来自samhan

18

内容来自zvvq,别采集哟

19 copyright zvvq

20

zvvq

21 内容来自zvvq

22 zvvq

23

本文来自zvvq

24 内容来自zvvq

25

本文来自zvvq

26 zvvq好,好zvvq

27

本文来自zvvq

28

内容来自samhan

29 内容来自zvvq

30

内容来自zvvq

31 内容来自samhan666

32

zvvq.cn

33 内容来自zvvq,别采集哟

34 zvvq好,好zvvq

35 内容来自zvvq,别采集哟

36

copyright zvvq

37 copyright zvvq

38

zvvq.cn

39 内容来自zvvq

40 内容来自samhan

41 本文来自zvvq

42

内容来自samhan

43 内容来自zvvq,别采集哟

44 内容来自zvvq,别采集哟

45

内容来自zvvq,别采集哟

46

内容来自zvvq

47

内容来自samhan

48 内容来自samhan666

49 本文来自zvvq

50 本文来自zvvq

51

本文来自zvvq

52 内容来自samhan

53 内容来自samhan

54

zvvq.cn

55 copyright zvvq

56

内容来自samhan

57

zvvq好,好zvvq

58

内容来自zvvq

59 内容来自zvvq,别采集哟

60

内容来自zvvq,别采集哟

61

内容来自samhan666

62 zvvq.cn

63

内容来自zvvq,别采集哟

64

本文来自zvvq

65

内容来自zvvq,别采集哟

66

内容来自samhan666

67

内容来自zvvq,别采集哟

68

内容来自samhan666

69 内容来自samhan666

70

内容来自samhan

71

内容来自samhan666

72

本文来自zvvq

73 copyright zvvq

74

本文来自zvvq

75 内容来自zvvq

76 内容来自zvvq,别采集哟

77 内容来自zvvq

78

内容来自zvvq

79

内容来自zvvq,别采集哟

80 zvvq好,好zvvq

81 copyright zvvq

82

copyright zvvq

83 内容来自zvvq,别采集哟

84

copyright zvvq

85

copyright zvvq

86

copyright zvvq

87 zvvq.cn

88 内容来自samhan

89 本文来自zvvq

90

内容来自zvvq,别采集哟

91

内容来自samhan666

92 内容来自zvvq,别采集哟

93 内容来自zvvq,别采集哟

94

内容来自zvvq

95 内容来自samhan

96 内容来自zvvq,别采集哟

97 copyright zvvq

98

内容来自samhan666

99 zvvq.cn

100 zvvq.cn

101

zvvq好,好zvvq

102 内容来自zvvq,别采集哟

103 内容来自zvvq,别采集哟

104

zvvq好,好zvvq

105

内容来自zvvq

106 内容来自zvvq

107 内容来自samhan

108 zvvq好,好zvvq

109 本文来自zvvq

110 zvvq好,好zvvq

111

内容来自samhan666

112

copyright zvvq

113 内容来自zvvq,别采集哟

114 内容来自zvvq

115

zvvq

116

内容来自zvvq

117 内容来自samhan666

var express = require('express');

内容来自zvvq,别采集哟

var crypto = require('crypto'); 内容来自samhan

var router = express.Router(); 内容来自samhan

var db=require('../db');

内容来自samhan666

var User=require('../models/user'); zvvq好,好zvvq

var Post=require('../models/post');

内容来自samhan

/* GET home page. */ zvvq.cn

router.get('/', function(req, res, next) {

zvvq.cn

Post.find({},function(err,posts){ zvvq好,好zvvq

if(err){ zvvq.cn

req.session.message=err.message; zvvq好,好zvvq

return res.redirect('/');

zvvq好,好zvvq

} zvvq

res.render('index',{

zvvq好,好zvvq

posts:posts

内容来自zvvq

});

内容来自zvvq

});

zvvq好,好zvvq

});

zvvq

//发表微博

内容来自samhan

router.post('/post',function(req, res, next){

内容来自samhan

var currentUser=req.session.user;

内容来自zvvq

var post=new Post({ 内容来自samhan

user:currentUser.name, 本文来自zvvq

post:req.body.article, zvvq

updated:getTime(new Date())

本文来自zvvq

});

内容来自samhan

post.save(function(err){ 本文来自zvvq

if(err){ zvvq

req.session.message=err.message; 内容来自samhan666

return res.redirect('/reg');

内容来自samhan

}

内容来自samhan

req.session.success="发表成功"; zvvq.cn

res.redirect('/users/'+currentUser.name); zvvq

});

本文来自zvvq

}); zvvq好,好zvvq

function getTime(date){ zvvq.cn

return date.getFullYear()+

zvvq.cn

"-"+date.getMonth()+1+"-"+ 内容来自samhan666

date.getDate()+" "+ zvvq好,好zvvq

date.getHours()+":"+ 本文来自zvvq

date.getMinutes();

内容来自zvvq

}

内容来自samhan

router.get('/reg', isLogin);

zvvq.cn

//用户进入注册页面

zvvq

router.get('/reg',function(req,res){

内容来自samhan

res.render('reg',{title:"用户注册"});

本文来自zvvq

}); 内容来自zvvq,别采集哟

router.post('/reg', isLogin); 本文来自zvvq

//用户点击注册按钮

内容来自samhan

router.post('/reg',function(req,res){

内容来自samhan

if(req.body['password']!= req.body['passwordconf']){

内容来自samhan

req.session.error="两次密码不一致";

zvvq

return res.redirect('/reg'); 内容来自samhan

}

内容来自zvvq

var md5=crypto.createHash('md5'); copyright zvvq

var password=md5.update(req.body.password).digest('base64');

内容来自samhan

var newUser=new User({ 内容来自zvvq,别采集哟

name:req.body['username'],

zvvq好,好zvvq

password:password 本文来自zvvq

});

内容来自samhan666

User.findOne({name:newUser.name},function(err,user){

内容来自samhan

if(user){

本文来自zvvq

err="用户名已经存在";

内容来自samhan666

} 内容来自zvvq

if(err){ 内容来自zvvq,别采集哟

req.session.error=err;

zvvq好,好zvvq

return res.redirect('/reg');

内容来自samhan

} 内容来自samhan666

newUser.save(function(err){

内容来自zvvq

if(err){ 内容来自zvvq,别采集哟

req.session.error=err.message; 内容来自samhan

return res.redirect('/reg');

本文来自zvvq

}

zvvq好,好zvvq

req.session.user=newUser; 内容来自samhan666

req.session.success="注册成功";

内容来自samhan666

res.redirect('/'); zvvq

}); 内容来自samhan

}); zvvq好,好zvvq

}); copyright zvvq

router.get('/login',isLogin); zvvq.cn

router.get('/login',function(req,res){

本文来自zvvq

res.render('login',{title:"用户登陆"}); zvvq

});

内容来自zvvq

router.post('/login',isLogin); zvvq.cn

router.post('/login',function(req,res){

内容来自samhan666

var md5=crypto.createHash('md5');

内容来自samhan666

var password=md5.update(req.body.password).digest('base64');

内容来自zvvq

User.findOne({name:req.body.username},function(err,user){ 内容来自samhan666

if(!user){ 内容来自zvvq

req.session.error="用户不存在";

内容来自samhan666

return res.redirect('/login');

zvvq好,好zvvq

}

本文来自zvvq

if(user.password!=password){

本文来自zvvq

req.session.error="密码错误"; 内容来自samhan

return res.redirect('/login'); zvvq好,好zvvq

} zvvq好,好zvvq

req.session.user=user;

内容来自samhan666

req.session.success="登录成功"; 本文来自zvvq

res.redirect('/');

zvvq

}); 内容来自zvvq,别采集哟

});

copyright zvvq

router.get('/logout',function(req,res){

本文来自zvvq

req.session.user=null;

copyright zvvq

res.redirect('/'); 内容来自zvvq

});

zvvq

function isLogin(req,res,next){

内容来自zvvq,别采集哟

if(req.session.user){

内容来自zvvq

req.session.message="用户已登录"; 内容来自samhan666

return res.redirect('/');

zvvq.cn

}

内容来自zvvq,别采集哟

next(); 内容来自samhan

}

内容来自samhan

module.exports = router;

内容来自zvvq,别采集哟

登录后复制

上述代码1-6行都是对外部模块的引入,8-19行是对首页路由/的处理代码。117行将该模块定义为router供外部调用。我们主要看54-83行,这些代码就是用户注册的代码,54行监听来自用户对于/reg路由的post请求,首先判断两次密码是否一致,如果不一致在session中存储一个错误信息然后跳转到到当前页面显示错误信息,该错误信息供模板引擎显示给用户。如果两次密码一致首先对密码进行md5加密,使用的是nodejs提供的核心模块crypto,并生成一个对象模型User,该对象模型是mongoose中提供的一个model的实例,mongoose在它上面定义了一些操作数据库的方法。然后调用这个实例的findOne方法检测该用户是否已经存在,如果存在就保存错误信息到session并跳转到当前页显示错误。如果不存在这样一个用户就使用save方法进行用户信息保存,注册成功后将用户信息保存在session中,并保存一个success的提示信息,然后跳转到首页。这里需要注意一个坑,以前做php或者.net的时候,我们通常都是先查询数据库等数据库返回结果提示用户是否存在之后再进行用户的save然后在跳转,这是一种同步方式,跳转操作需要等待findOne操作返回结果之后才能进行。而nodejs中采用异步IO,最后的跳转操作需要放在findOne操作的回调函数中进行,跳转操作不必等待findone操作结束后执行,两者是异步的。如果将最后的redirect操作放在findOne操作外部而不是回调函数中,你会在控制台上得到一个Cant set headers after they are sent的错误,这是因为在fineOne以及save操作之前已经进行行了跳转,response响应已经结束,不能够重复响应请求。

内容来自samhan

到目前为止,用户注册模块基本上已经差不多完成了,最后需要说一下如何在页面上显示提示信息或者错误信息,之前我们将提示信息或者错误信息都保存在了session中,jade要显示错误信息,它是不能够直接访问session的,在express2.X即原书中是利用req.flash API+动态视图助手来实现的,就是发生错误的时候先将其利用req.flash方法存储下来,然后利用动态视图助手结合模板去渲染给用户。express4.X废弃了这种方式,我们可以利用req.flash 的原理来自己模拟一个这种机制,同时利用res.locals变量被保存起来,模板在渲染的时候是能够访问到服务端这个变量的。关于res.locals的更多介绍请查看文档。 内容来自zvvq

为了模拟这种req.flash机制,我们在项目入口文件app.js(项目根目录下)添加一段代码如下:

copyright zvvq

1

zvvq

2

内容来自samhan

3 zvvq.cn

4

内容来自samhan

5

zvvq好,好zvvq

6 内容来自zvvq

7 内容来自samhan

8 zvvq好,好zvvq

9 zvvq好,好zvvq

10 zvvq

11

内容来自zvvq,别采集哟

12 内容来自zvvq

13 内容来自zvvq

14

内容来自samhan

15 内容来自zvvq,别采集哟

16

内容来自zvvq,别采集哟

17

copyright zvvq

18

内容来自samhan

19 内容来自samhan666

20 内容来自zvvq

21 zvvq.cn

22 zvvq好,好zvvq

23 本文来自zvvq

app.use(function(req,res,next){

内容来自samhan

//  res.locals.user=req.session.user;

copyright zvvq

var err=req.session.error;

内容来自samhan

var success=req.session.success; 内容来自samhan

var user=req.session.user; 内容来自samhan

var mess=req.session.message;

zvvq

delete req.session.success;

zvvq好,好zvvq

delete req.session.error;

copyright zvvq

delete req.session.message; zvvq

if(err){

内容来自samhan

res.locals.message="*"+err;

zvvq好,好zvvq

}

zvvq好,好zvvq

if(mess){ copyright zvvq

res.locals.message="*"+mess;

内容来自zvvq,别采集哟

}

zvvq

if(success){

内容来自samhan666

res.locals.success=success; 内容来自zvvq,别采集哟

} zvvq.cn

if(user){

内容来自zvvq

res.locals.user=user.name;

内容来自zvvq

}

本文来自zvvq

next(); 本文来自zvvq

}); 内容来自zvvq

登录后复制

这段代码的意思是用户请求和响应的时候,捕获session中存储的错误信息和用户提示,将其存储在response.locals变量中,这样模板就能够获取。对于错误信息和提示,由于只使用一次,存储后立即使用delete删除,对于用户信息,需要持久保存下来,则不删除。 内容来自samhan

这样,就能够显示用户提示或者错误信息。 copyright zvvq

下面演示一下完整的用户注册流程以及错误信息提示。 内容来自samhan

当用户名存在或密码不一致时, zvvq.cn

内容来自samhan666

当注册成功后跳转到首页并显示用户注册成功

本文来自zvvq

本文来自zvvq

同时对于注册成功和登陆成功拥有不同提示,如果该用户已经是登录状态则显示退出和发表文章按钮,如果没有登录,则显示的是登陆和立即注册按钮。 内容来自samhan

以上就是利用nodejs及express,mongoose,mongoDB,jade进行web开发的主要流程,由于该项目是对nodejs web开发指南一书中微博项目的重构,所以完整版的项目代码还有用户权限控制(已登录用户不能够注册或登陆并提示),用户进入个人页面发布微博并列表显示,同时首页显示最近发布的微博信息等功能。完整版代码点这里,由于篇幅以及时间问题,上述要点不可能一一展开讨论,本文就作为一个提纲,是对nodejs web开发的一个综述。 内容来自samhan

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网! zvvq

相关推荐:

zvvq

关于NodeJS、NPM安装配置步骤(windows版本) 以及环境变量的介绍

本文来自zvvq

基于webpack4搭建的react项目框架的方法 内容来自zvvq

以上就是如何快速使用node.js进行web开发的详细内容,更多请关注php中文网其它相关文章! 内容来自zvvq