当前位置: 首页 > news >正文

二级域名网站建设移动端开发语言

二级域名网站建设,移动端开发语言,中网自助建站,团员团干部如何登录到系统学习环境 Node.js #xff1a; 0.10.22 Express #xff1a; 3.4.4 MongoDB #xff1a; 2.4.8 快速开始 安装 Express express 是 Node.js 上最流行的 Web 开发框架#xff0c;正如他的名字一样#xff0c;使用它我们可以快速的开发一个 Web 应用。我们用 express 来搭…学习环境 Node.js 0.10.22 Express 3.4.4 MongoDB 2.4.8 快速开始 安装 Express express 是 Node.js 上最流行的 Web 开发框架正如他的名字一样使用它我们可以快速的开发一个 Web 应用。我们用 express 来搭建我们的博客打开命令行输入 $ npm install -g express我们需要用全局模式安装 express因为只有这样我们才能在命令行中使用它。 新建一个工程 笔者是在 Windows 下开发和撰写的教程假如你在 Linux 或 Mac 操作系统下开发应用本教程也几乎同样适用。 我们约定今后的学习把 D:\blog 文件夹作为我们的工程目录。 windows 下打开 cmd 切换到 D 盘输入 $ express -e blog注意express 3.x 中使用 ejs 不再是 -t ejs 而是 -e可以输入 express -h 查看。 然后输入 $ cd blog npm install安装所需模块如下图所示 安装完成后输入 $ node app此时命令行中会显示 Express server listening on port 3000在浏览器里访问 localhost:3000如下所示 至此我们用 express 初始化了一个工程项目并指定使用 ejs 模板引擎下一节我们讲解工程的内部结构。 工程结构 我们回头看看生成的工程目录里面都有什么打开我们的 blog 文件夹里面如图所示 app.js启动文件或者说入口文件package.json存储着工程的信息及模块依赖当在 dependencies 中添加依赖的模块时运行 npm installnpm 会检查当前目录下的 package.json并自动安装所有指定的模块node_modules存放 package.json 中安装的模块当你在 package.json 添加依赖的模块并安装后存放在这个文件夹下public存放 image、css、js 等文件routes存放路由文件views存放视图文件或者说模版文件 打开 app.js让我们看看里面究竟有什么东西 /*** Module dependencies.*/var express require(express); var routes require(./routes); var user require(./routes/user); var http require(http); var path require(path);var app express();// all environments app.set(port, process.env.PORT || 3000); app.set(views, __dirname /views); app.set(view engine, ejs); app.use(express.favicon()); app.use(express.logger(dev)); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(path.join(__dirname, public)));// development only if (development app.get(env)) {app.use(express.errorHandler()); }app.get(/, routes.index); app.get(/users, user.list);http.createServer(app).listen(app.get(port), function(){console.log(Express server listening on port app.get(port)); });这里我们通过 require() 加载了 express、http、path 模块以及 routes 文件夹下的 index.js 和 user.js 文件。更多关于模块及模块加载顺序的信息请查阅官方文档的 Modules 章节。 因为 express 框架是严重依赖 connect 框架一个 Node.js 的中间件框架创建而成的所以我们可查阅 connect 文档 http://www.senchalabs.org/connect/express 文档 http://expressjs.com/api.html了解更多内容。 app.set(port, process.env.PORT || 3000)设置端口为 process.env.PORT 或 3000。app.set(views, __dirname /views)设置 views 文件夹为存放视图文件的目录即存放模板文件的地方__dirname 为全局变量存储当前正在执行的脚本所在的目录。app.set(view engine, ejs)设置视图模版引擎为 ejs。app.use(express.favicon())connect 内建的中间件使用默认的 favicon 图标如果想使用自己的图标需改为 app.use(express.favicon(__dirname /public/images/favicon.ico)); 这里我们把自定义的 favicon.ico 放到了 /public/images 文件夹下。app.use(express.logger(dev))connect 内建的中间件在开发环境下使用在终端显示简单的日志比如在启动 app.js 后访问 localhost:3000终端会输出 Express server listening on port 3000 GET / 200 21ms - 206b GET /stylesheets/style.css 304 4ms假如你去掉这一行代码不管你怎么刷新网页终端都只有一行 Express server listening on port 3000。app.use(express.bodyParser())connect 内建的中间件用来解析请求体支持 application/json application/x-www-form-urlencoded, 和 multipart/form-data。 注意最新的 Express 生成的工程也许删除了 app.use(express.bodyParser()) 使用了 app.use(express.json()); app.use(express.urlencoded());其实app.use(express.bodyParser()) 相当于 app.use(express.json()); app.use(express.urlencoded()); app.use(express.multipart());这里我们仍然使用 bodyParser 删除 app.use(express.json()); 和 app.use(express.urlencoded());添加 app.use(express.bodyParser())。 app.use(express.methodOverride())connect 内建的中间件可以协助处理 POST 请求伪装 PUT、DELETE 和其他 HTTP 方法。app.use(app.router)调用路由解析的规则。app.use(express.static(path.join(__dirname, public)))connect 内建的中间件设置根目录下的 public 文件夹为存放 image、css、js 等静态文件的目录。 if (development app.get(env)) {app.use(express.errorHandler()); }开发环境下的错误处理输出错误信息。app.get(/, routes.index)路由控制器如果用户访问 / 主页则由 routes.index 来处理routes/index.js 内容如下 exports.index function(req, res){res.render(index, { title: Express }); };通过 exports.index 导出 index 函数接口app.get(/, routes.index) 相当于 app.get(/, function(req, res){res.render(index, { title: Express }); });res.render(index, { title: Express })使用 ejs 模板引擎解析 views/index.ejs因为我们之前通过 app.set(views, __dirname /views) 设置了模版文件默认存储在 views 文件夹下并传入一个对象这个对象只有一个 title 属性它的值为字符串 Express 即用字符串 Express 替换 views/index.ejs 中所有 title 变量这就是我们所说的渲染视图或者说渲染模版。后面我们将会了解更多关于模板引擎的内容。 http.createServer(app).listen(app.get(port), function(){console.log(Express server listening on port app.get(port)); });这段代码的意思是创建 http 服务器并监听 3000 端口成功后在命令行中显示 Express server listening on port 3000然后我们就可以在浏览器访问 localhost:3000 了。 这一小节我们学习了如何创建一个工程并启动它了解了工程的大体结构下一节我们将学习 express 的基本使用及路由控制。 路由控制 工作原理 前面提到过 app.js 中 app.get(/, routes.index) 可以用以下代码取代 app.get(/, function(req, res){res.render(index, { title: Express }); };)这段代码的意思是当访问主页时调用 ejs 模板引擎来渲染 index.ejs 模版文件即将 title 变量全部替换为字符串 Express生成静态页面并显示在浏览器中。 我们来作一些修改以上代码实现了路由的功能我们当然可以不要 routes/index.js 文件把实现路由功能的代码都放在 app.js 里但随着时间的推移 app.js 会变得臃肿难以维护这也违背了代码模块化的思想所以我们把实现路由功能的代码都放在 routes/index.js 里。官方给出的写法是在 app.js 中实现了简单的路由分配然后再去 index.js 中找到对应的路由函数最终实现路由功能。我们不妨把路由控制器和实现路由功能的函数都放到 index.js 里app.js 中只有一个总的路由接口。 打开 app.js删除 app.get(/, routes.index); app.get(/users, user.list);注意目前我们用不到 routes/user.js也可以删除这个文件同时删除 app.js 中 var user require(./routes/user);。 在 app.js 最后添加一行代码 routes(app);修改 index.js 如下 module.exports function(app) {app.get(/, function (req, res) {res.render(index, { title: Express });}); };现在再运行你的 app你会发现主页毫无二致。这里我们在 routes/index.js 中通过 module.exports 导出了一个函数接口在 app.js 中通过 require 加载了 index.js 然后通过 routes(app) 调用了 index.js 导出的函数。 路由规则 express 封装了多种 http 请求方式我们主要只使用 get 和 post 两种即 app.get() 和 app.post() 。 app.get() 和 app.post() 的第一个参数都为请求的路径第二个参数为处理请求的回调函数回调函数有两个参数分别是 req 和 res代表请求信息和响应信息 。路径请求及对应的获取路径有以下几种形式 req.query // GET /search?qtobiferret req.query.q // tobi ferret // GET /shoes?orderdescshoe[color]blueshoe[type]converse req.query.order // desc req.query.shoe.color // blue req.query.shoe.type // converse req.body // POST user[name]tobiuser[email]tobilearnboost.com req.body.user.name // tobi req.body.user.email // tobilearnboost.com // POST { name: tobi } req.body.name // tobi req.params // GET /user/tj req.params.name // tj // GET /file/javascripts/jquery.js req.params[0] // javascripts/jquery.js **req.param(name)**// ?nametobi req.param(name) // tobi // POST nametobi req.param(name) // tobi // /user/tobi for /user/:name req.param(name) // tobi 不难看出 req.query 处理 get 请求获取 get 请求参数req.params 处理 /:xxx 形式的 get 或 post 请求获取请求参数req.body 处理 post 请求获取 post 请求体 req.param() 处理 get 和 post 请求但查找优先级由高到低为 req.params→req.body→req.query路径规则还支持正则表达式更多请查阅 Express 官方文档 。 添加路由规则 当我们访问 localhost:3000 时会显示 当我们访问 localhost:3000/nswbmw 这种不存在的页面时就会显示 这是因为不存在 /nswbmw 的路由规则而且它也不是一个 public 目录下的文件所以 express 返回了 404 Not Found 的错误。下面我们来添加这条路由规则使得当访问 localhost:3000/nswbmw 时页面显示 hello,world! 注意以下修改仅用于测试看到效果后再把代码还原回来。 修改 index.js在 app.get(/) 函数后添加一条路由规则 app.get(/nswbmw, function (req, res) {res.send(hello.world!); });此时访问 localhost:3000/nswbmw 页面显示如下 很简单吧这一节我们学习了基本的路由规则及如何添加一条路由规则下一节我们将学习模板引擎的知识。 模版引擎 什么是模板引擎 模板引擎Template Engine是一个将页面模板和要显示的数据结合起来生成 HTML 页面的工具。 如果说上面讲到的 express 中的路由控制方法相当于 MVC 中的控制器的话那模板引擎就相当于 MVC 中的视图。 模板引擎的功能是将页面模板和要显示的数据结合起来生成 HTML 页面。它既可以运 行在服务器端又可以运行在客户端大多数时候它都在服务器端直接被解析为 HTML解析完成后再传输给客户端因此客户端甚至无法判断页面是否是模板引擎生成的。有时候模板引擎也可以运行在客户端即浏览器中典型的代表就是 XSLT它以 XML 为输入在客户端生成 HTML 页面。但是由于浏览器兼容性问题XSLT 并不是很流行。目前的主流还是由服务器运行模板引擎。 在 MVC 架构中模板引擎包含在服务器端。控制器得到用户请求后从模型获取数据调用模板引擎。模板引擎以数据和页面模板为输入生成 HTML 页面然后返回给控制器由控制器交回客户端。 ——《Node.js开发指南》 什么是 ejs ? ejs 是模板引擎的一种也是我们这个教程中使用的模板引擎因为它使用起来十分简单而且与 express 集成良好。 使用模板引擎 前面我们通过以下两行代码设置了模板文件的存储位置和使用的模板引擎 app.set(views, __dirname /views); app.set(view engine, ejs);注意我们通过 express -e blog 只是初始化了一个使用 ejs 模板引擎的工程而已比如 node_modules 下添加了 ejs 模块views 文件夹下有 index.ejs 。并不是说强制该工程只能使用 ejs 不能使用其他的模板引擎比如 jade真正指定使用哪个模板引擎的是 app.set(view engine, ejs); 。 在 routes/index.js 中通过调用 res.render() 渲染模版并将其产生的页面直接返回给客户端。它接受两个参数第一个是模板的名称即 views 目录下的模板文件名扩展名 .ejs 可选。第二个参数是传递给模板的数据对象用于模板翻译。 打开 views/index.ejs 内容如下 index.ejs !DOCTYPE html htmlheadtitle% title %/titlelink relstylesheet href/stylesheets/style.css //headbodyh1% title %/h1pWelcome to % title %/p/body /html当我们 res.render(index, { title: Express }); 时模板引擎会把 % title % 替换成 Express然后把替换后的页面显示给用户。 渲染后生成的页面代码为 !DOCTYPE html htmlheadtitleExpress/titlelink relstylesheet href/stylesheets/style.css //headbodyh1Express/h1pWelcome to Express/p/body /html注意我们通过 app.use(express.static(path.join(__dirname, public))) 设置了静态文静目录为 public 文件夹所以上面代码中的 href/stylesheets/style.css 就相当于 hrefpublic/stylesheets/style.css 。 ejs 的标签系统非常简单它只有以下三种标签 % code %JavaScript 代码。% code %显示替换过 HTML 特殊字符的内容。%- code %显示原始 HTML 内容。注意 % code % 和 %- code % 的区别当变量 code 为普通字符串时两者没有区别。当 code 比如为 h1hello/h1 这种字符串时% code % 会原样输出 h1hello/h1而 %- code % 则会显示 H1 大的 hello 字符串。 我们可以在 % % 内使用 JavaScript 代码。下面是 ejs 的官方示例 The Data supplies: [mop, broom, duster]The Template ul % for(var i0; isupplies.length; i) {%li% supplies[i] %/li % } % /ulThe Result ullimop/lilibroom/liliduster/li /ul我们可以用上述三种标签实现页面模板系统能实现的任何内容。 页面布局 Express 3.x 中我们不再使用 layout.ejs 进行页面布局转而使用 include 来替代。include 的简单使用如下 index.ejs %- include a % hello,world! %- include b %a.ejs this is a.ejsb.ejs this is b.ejs最终 index.ejs 会显示 this is a.ejs hello,world! this is b.ejs这一节我们学习了模版引擎的相关知识下一节我们正式开始学习如何从头开始搭建一个多人博客。 搭建多人博客 功能分析 搭建一个简单的具有多人注册、登录、发表文章、登出功能的博客。 设计目标 未登录主页左侧导航显示 home、login、register右侧显示已发表的文章、发表日期及作者。 登陆后主页左侧导航显示 home、post、logout右侧显示已发表的文章、发表日期及作者。 用户登录、注册、发表成功以及登出后都返回到主页。 未登录 主页 登录页 注册页 登录后 主页: 发表页 注意没有登出页当点击 LOGOUT 后退出登陆并返回到主页。 路由规划 我们已经把设计的构想图贴出来了接下来的任务就是完成路由规划了。路由规划或者说控制器规划是整个网站的骨架部分因为它处于整个架构的枢纽位置相当于各个接口之间的粘合剂所以应该优先考虑。 根据构思的设计图我们作以下路由规划 / 首页 /login 用户登录 /reg 用户注册 /post 发表文章 /logout 登出我们要求 /login 和 /reg 只能是未登录的用户访问而 /post 和 /logout 只能是已登录的用户访问。左侧导航列表则针对已登录和未登录的用户显示不同的内容。 修改 index.js 如下 module.exports function(app) {app.get(/, function (req, res) {res.render(index, { title: 主页 });});app.get(/reg, function (req, res) {res.render(reg, { title: 注册 });});app.post(/reg, function (req, res) {});app.get(/login, function (req, res) {res.render(login, { title: 登录 });});app.post(/login, function (req, res) {});app.get(/post, function (req, res) {res.render(post, { title: 发表 });});app.post(/post, function (req, res) {});app.get(/logout, function (req, res) {}); };如何针对已登录和未登录的用户显示不同的内容呢或者说如何判断用户是否已经登陆了呢进一步说如何记住用户的登录状态呢我们通过引入会话session机制记录用户登录状态还要访问数据库来保存和读取用户信息。下一节我们将学习如何使用数据库。 使用数据库 MongoDB简介 MongoDB 是一个基于分布式文件存储的 NoSQL非关系型数据库的一种由 C 语言编写旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 支持的数据结构非常松散是类似 json 的 bjson 格式因此可以存储比较复杂的数据类型。MongoDB 最大的特点是他支持的查询语言非常强大其语法有点类似于面向对象的查询语言几乎可以实现类似关系数据库单表查询的绝大部分功能而且还支持对数据建立 索引。 MongoDB 没有关系型数据库中行和表的概念不过有类似的文档和集合的概念。文档是 MongoDB 最基本的单位每个文档都会以唯一的 _id 标识文档的属性为 key/value 的键值对形式文档内可以嵌套另一个文档因此可以存储比较复杂的数据类型。集合是许多文档的总和一个数据库可以有多个集合一个集合可以有多个文档。 下面是一个 MongoDB 文档的示例 { _id : ObjectId( 4f7fe8432b4a1077a7c551e8 ),name : nswbmw,age : 22,email : [ xxx126.com, xxxgmail.com ],family : {mother : { ... },father : { ... },sister : {name : miaomiao,age : 27,email : xxx163.com,family : {mother : { ... },father : { ... },brother : { ... },husband : { ... },son : { ... }}}} }更多有关 MongoDB 的知识请参阅 《mongodb权威指南》或查阅http://www.mongodb.org/ 安装MongoDB 安装 mongodb 很简单去官网http://www.mongodb.org/downloads下载最新版的 mongodb解压到 D 盘并把文件夹重命名为 mongodb并在 mongodb 文件夹里新建 blog 文件夹作为我们博客内容的存储目录。打开命令行切换到 d:\mongodb\bin 目录下然后输入 mongod -dbpath d:\mongodb\blog以上命令的意思是设置 blog 文件夹作为我们工程的存储目录并启动数据库。为了方便以后使用数据库我们在桌面上新建 启动mongodb.bat 并写入 d:\mongodb\bin\mongod.exe -dbpath d:\mongodb\blog这样我们以后只需运行桌面上的 启动mongodb.bat 就可启动数据库了。 连接MongoDB 数据库虽然安装并启动成功了但我们需要连接数据库后才能使用数据库。怎么才能在 Node.js 中使用 MongoDB 呢我们使用官方提供的 node-mongodb-native 驱动模块打开 package.json在 dependencies 中添加一行代码 {name: blog,version: 0.0.1,private: true,scripts: {start: node app.js},dependencies: {express: *,ejs: *,mongodb: *} }然后运行 npm install 更新依赖的模块稍等片刻后 mongodb 模块就下载并安装完成了。 接下来在工程的根目录中创建 settings.js 文件用于保存该博客工程的配置信息比如数据库的连接信息。我们将数据库命名为 blog因为数据库服务器在本地所以 settings.js 文件的内容如下 module.exports { cookieSecret: myblog, db: blog, host: localhost }; 其中 db 是数据库的名称host 是数据库的地址。cookieSecret 用于 Cookie 加密与数据库无关我们留作后用。 接下来在根目录下新建 models 文件夹并在 models 文件夹下新建 db.js 添加如下代码 var settings require(../settings),Db require(mongodb).Db,Connection require(mongodb).Connection,Server require(mongodb).Server; module.exports new Db(settings.db, new Server(settings.host, Connection.DEFAULT_PORT), {safe: true});其中通过 new Db(settings.db, new Server(settings.host, Connection.DEFAULT_PORT), {safe: true}); 设置数据库名、数据库地址和数据库端口创建了一个数据库连接实例并通过 module.exports 导出该实例。这样我们就可以通过 require 这个文件来对数据库进行读写了。 会话支持 会话是一种持久的网络协议用于完成服务器和客户端之间的一些交互行为。会话是一个比连接粒度更大的概念 一次会话可能包含多次连接每次连接都被认为是会话的一次操作。在网络应用开发中有必要实现会话以帮助用户交互。例如网上购物的场景用户浏览了多个页 面购买了一些物品这些请求在多次连接中完成。许多应用层网络协议都是由会话支持的如 FTP、Telnet 等而 HTTP 协议是无状态的本身不支持会话因此在没有额外手段的帮助下前面场景中服务器不知道用户购买了什么。 为了在无状态的 HTTP 协议之上实现会话Cookie 诞生了。Cookie 是一些存储在客户端的信息每次连接的时候由浏览器向服务器递交服务器也向浏览器发起存储 Cookie 的请求依靠这样的手段服务器可以识别客户端。我们通常意义上的 HTTP 会话功能就是这样实现的。具体来说浏览器首次向服务器发起请求时服务器生成一个唯一标识符并发送给客户端浏览器浏览器将这个唯一标识符存储在 Cookie 中以后每次再发起请求客户端浏览器都会向服务器传送这个唯一标识符服务器通过这个唯一标识符来识别用户。 对于开发者来说我们无须关心浏览器端的存储需要关注的仅仅是如何通过这个唯一标识符来识别用户。很多服务端脚本语言都有会话功能如 PHP把每个唯一标识符存储到文件中。 ——《Node.js开发指南》 express 也提供了会话中间件默认情况下是把用户信息存储在内存中但我们既然已经有了 MongoDB不妨把会话信息存储在数据库中便于持久维护。为了使用这一功能我们首先要获取一个叫做 connect-mongo https://github.com/kcbanner/connect-mongo的模块在 package.json 中添加一行代码 {name: blog,version: 0.0.1,private: true,scripts: {start: node app.js},dependencies: {express: *,ejs: *,mongodb: *,connect-mongo: *} }运行 npm install 安装模块。然后打开 app.js在 var path require(path); 后添加以下代码 var MongoStore require(connect-mongo)(express); var settings require(./settings);在 app.use(express.methodOverride()); 后添加 app.use(express.cookieParser()); app.use(express.session({secret: settings.cookieSecret,key: settings.db,//cookie namecookie: {maxAge: 1000 * 60 * 60 * 24 * 30},//30 daysstore: new MongoStore({db: settings.db}) }));其中 express.cookieParser() 是 Cookie 解析的中间件。express.session() 则提供会话支持secret 用来防止篡改 cookiekey 的值为 cookie 的名字通过设置 cookie 的 maxAge 值设定 cookie 的生存期这里我们设置 cookie 的生存期为 30 天设置它的 store 参数为 MongoStore 实例把会话信息存储到数据库中以避免丢失。在后面的小节中我们可以通过 req.session 获取当前用户的会话对象获取用户的相关信息。 注册和登陆 我们已经准备好了数据库访问和会话的相关信息接下来我们完成用户注册和登录功能。 页面设计 首先我们来完成主页、登录页和注册页的页面设计。 修改 views/index.ejs 如下 %- include header % 这是主页 %- include footer %在 views 文件夹下新建 header.ejs添加如下代码 !DOCTYPE html html head meta charsetUTF-8 / titleBlog/title link relstylesheet href/stylesheets/style.css /head bodyheader h1% title %/h1 /headernav spana title主页 href/home/a/span spana title登录 href/loginlogin/a/span spana title注册 href/regregister/a/span /navarticle新建 footer.ejs添加如下代码 /article /body /html修改 public/stylesheets/style.css 如下 /* inspired by http://yihui.name/cn/ */ *{padding:0;margin:0;} body{width:600px;margin:2em auto;padding:0 2em;font-size:14px;font-family:Microsoft YaHei;} p{line-height:24px;margin:1em 0;} header{padding:.5em 0;border-bottom:1px solid #cccccc;} nav{position:fixed;left:12em;font-family:Microsoft YaHei;font-size:1.1em;text-transform:uppercase;width:9em;text-align:right;} nav a{display:block;text-decoration:none;padding:.7em 1em;color:#000000;} nav a:hover{background-color:#ff0000;color:#f9f9f9;-webkit-transition:color .2s linear;} article{font-size:16px;padding-top:.5em;} article a{color:#dd0000;text-decoration:none;} article a:hover{color:#333333;text-decoration:underline;} .info{font-size:14px;}运行 app 主页显示如下 接下来在 views 文件夹下新建 login.ejs内容如下 %- include header % form methodpost用户名input typetext namename/br /密码 input typepassword namepassword/br /input typesubmit value登录/ /form %- include footer %登录页面显示如下 在 views 文件夹下新建 reg.ejs内容如下 %- include header % form methodpost用户名 input typetext namename/br /密码 input typepassword namepassword/br /确认密码input typepassword namepassword-repeat/br /邮箱 input typeemail nameemail/br /input typesubmit value注册/ /form %- include footer %注册页面显示如下 至此未登录时的主页、注册页、登录页都已经完成。 在桌面新建 启动app.bat 并写入 node d:\blog\app以后我们就可以通过依次打开 启动mongodb.bat 和 启动app.bat 来启动我们的博客了。 注意每次我们更新代码后都需要手动停止并重启应用使用 supervisor 模块可以解决这个问题每当我们保存修改的文件时supervisor 都会自动帮我们重启应用。通过 $ npm install -g supervisor安装 supervisor 。使用 supervisor 命令启动 app.js $ supervisor app我们可以将 启动app.bat 修改为 supervisor d:\blog\app。 此时依次运行 启动mongodb.bat 和 启动app.bat 去浏览器中查看一下效果吧。 页面通知 接下来我们实现用户的注册和登陆在这之前我们需要引入 flash 模块来实现页面通知即成功与错误信息的显示的功能。 什么是 flash? 我们所说的 flash 即 connect-flash 模块https://github.com/jaredhanson/connect-flashflash 是一个在 session 中用于存储信息的特定区域。信息写入 flash 下一次显示完毕后即被清除。典型的应用是结合重定向的功能确保信息是提供给下一个被渲染的页面。这个中间件是从 Express 2.x 提取出来的Express 3.x 不再支持但是通过 connect-flash 模块可以实现这个功能。 在 package.json 添加一行代码 {name: blog,version: 0.0.1,private: true,scripts: {start: node app.js},dependencies: {express: *,ejs: *,mongodb: *,connect-mongo: *,connect-flash: *} }然后 npm install 安装 connect-flash 模块。修改 app.js 在 var settings require(./settings); 后添加 var flash require(connect-flash);在 app.set(view engine, ejs); 后添加 app.use(flash());现在我们就可以使用 flash 功能了。 注册响应 前面我们已经完成了注册页当然现在点击注册是没有效果的因为我们还没有实现处理 POST 请求的功能下面就来实现它。 在 models 文件夹下新建 user.js添加如下代码 var mongodb require(./db);function User(user) {this.name user.name;this.password user.password;this.email user.email; };module.exports User;//存储用户信息 User.prototype.save function(callback) {//要存入数据库的用户文档var user {name: this.name,password: this.password,email: this.email};//打开数据库mongodb.open(function (err, db) {if (err) {return callback(err);//错误返回 err 信息}//读取 users 集合db.collection(users, function (err, collection) {if (err) {mongodb.close();return callback(err);//错误返回 err 信息}//将用户数据插入 users 集合collection.insert(user, {safe: true}, function (err, user) {mongodb.close();if (err) {return callback(err);//错误返回 err 信息}callback(null, user[0]);//成功err 为 null并返回存储后的用户文档});});}); };//读取用户信息 User.get function(name, callback) {//打开数据库mongodb.open(function (err, db) {if (err) {return callback(err);//错误返回 err 信息}//读取 users 集合db.collection(users, function (err, collection) {if (err) {mongodb.close();return callback(err);//错误返回 err 信息}//查找用户名name键值为 name 一个文档collection.findOne({name: name}, function (err, user) {mongodb.close();if (err) {return callback(err);//失败返回 err 信息}callback(null, user);//成功返回查询的用户信息});});}); };我们通过 User.prototype.save 实现了用户信息的存储通过 User.get 实现了用户信息的读取。 打开 index.js 在最前面添加如下代码 var crypto require(crypto),User require(../models/user.js);通过 require() 引入 crypto 模块和 user.js 用户模型文件crypto 是 Node.js 的一个核心模块我们用它生成散列值来加密密码。 修改 index.js 中 app.post(/reg) 如下 app.post(/reg, function (req, res) {var name req.body.name,password req.body.password,password_re req.body[password-repeat];//检验用户两次输入的密码是否一致if (password_re ! password) {req.flash(error, 两次输入的密码不一致!); return res.redirect(/reg);//返回注册页}//生成密码的 md5 值var md5 crypto.createHash(md5),password md5.update(req.body.password).digest(hex);var newUser new User({name: req.body.name,password: password,email: req.body.email});//检查用户名是否已经存在 User.get(newUser.name, function (err, user) {if (user) {req.flash(error, 用户已存在!);return res.redirect(/reg);//返回注册页}//如果不存在则新增用户newUser.save(function (err, user) {if (err) {req.flash(error, err);return res.redirect(/reg);//注册失败返回主册页}req.session.user user;//用户信息存入 sessionreq.flash(success, 注册成功!);res.redirect(/);//注册成功后返回主页});}); });注意我们把用户信息存储在了 session 里以后就可以通过 req.session.user 读取用户信息。 req.body 就是 POST 请求信息解析过后的对象例如我们要访问 POST 来的表单内的 namepassword 域的值只需访问 req.body[password] 或 req.body.password 即可。res.redirect 重定向功能实现了页面的跳转更多关于 res.redirect 的信息请查阅http://expressjs.com/api.html#res.redirect 。User在前面的代码中我们直接使用了 User 对象。User 是一个描述数据的对象即 MVC 架构中的模型。前面我们使用了许多视图和控制器这是第一次接触到模型。与视图和控制器不同模型是真正与数据打交道的工具没有模型网站就只是一个外壳不能发挥真实的作用因此它是框架中最根本的部分。现在启动应用在浏览器输入 localhost:3000 注册试试吧注册成功后显示如下 这样我们并不知道是否注册成功我们查看数据库中是否存入了用户的信息打开一个命令行切换到 d:\mongodb\bin\ 保证数据库已打开的前提下输入 可以看到用户信息已经成功存入数据库。 接下来我们实现当注册成功返回主页时左侧导航显示 HOME 、POST 、LOGOUT 右侧显示 注册成功 字样即添加 flash 的页面通知功能。 修改 header.ejs将 nav/nav 修改如下 nav spana title主页 href/home/a/span % if (user) { %spana title发表 href/postpost/a/spanspana title登出 href/logoutlogout/a/span % } else { %spana title登录 href/loginlogin/a/spanspana title注册 href/regregister/a/span % } % /nav在 article 后添加如下代码 % if (success) { %div% success %/div % } % % if (error) { %div% error % /div % } %修改 index.js 将 app.get(/) 修改如下 app.get(/, function (req, res) {res.render(index, {title: 主页,user: req.session.user,success: req.flash(success).toString(),error: req.flash(error).toString()}); });将 app.get(reg) 修改如下 app.get(/reg, function (req, res) {res.render(reg, {title: 注册,user: req.session.user,success: req.flash(success).toString(),error: req.flash(error).toString()}); });现在运行我们的博客注册成功后显示如下 我们通过对 session 的使用实现了对用户状态的检测再根据不同的用户状态显示不同的导航信息。 简单解释一下流程用户在注册成功后把用户信息存入 session 页面跳转到主页显示 注册成功 的字样。同时把 session 中的用户信息赋给变量 user 在渲染 index.ejs 文件时通过检测 user 判断用户是否在线根据用户状态的不同显示不同的导航信息。 success: req.flash(success).toString() 的意思是将成功的信息赋值给变量 success error: req.flash(error).toString() 的意思是将错误的信息赋值给变量 error 然后我们在渲染 ejs 模版文件时传递这两个变量来进行检测并显示通知。 登录与登出响应 现在我们来实现用户登录的功能。 打开 index.js 将 app.post(/login) 修改如下 app.post(/login, function (req, res) {//生成密码的 md5 值var md5 crypto.createHash(md5),password md5.update(req.body.password).digest(hex);//检查用户是否存在User.get(req.body.name, function (err, user) {if (!user) {req.flash(error, 用户不存在!); return res.redirect(/login);//用户不存在则跳转到登录页}//检查密码是否一致if (user.password ! password) {req.flash(error, 密码错误!); return res.redirect(/login);//密码错误则跳转到登录页}//用户名密码都匹配后将用户信息存入 sessionreq.session.user user;req.flash(success, 登陆成功!);res.redirect(/);//登陆成功后跳转到主页}); });接下来我们实现登出响应。修改 app.get(/logout) 如下 app.get(/logout, function (req, res) {req.session.user null;req.flash(success, 登出成功!);res.redirect(/);//登出成功后跳转到主页 });注意通过把 req.session.user 赋值 null 丢掉 session 中用户的信息实现用户的退出。 登录后页面显示如下 登出后页面显示如下 至此我们实现了用户注册与登陆的功能并且根据用户登录状态显示不同的导航。 页面权限控制 我们虽然已经完成了用户注册与登陆的功能但并不能阻止比如已经登陆的用户访问 localhost:3000/reg 页面读者可亲自尝试下。为此我们需要为页面设置访问权限。即注册和登陆页面应该阻止已登陆的用户访问登出及后面我们将要实现的发表页只对已登录的用 户开放。如何实现页面权限的控制呢我们可以把用户登录状态的检查放到路由中间件中在每个路径前增加路由中间件即可实现页面权限控制。我们添加 checkNotLogin 和 checkLogin 函数来实现这个功能。 function checkLogin(req, res, next) {if (!req.session.user) {req.flash(error, 未登录!); res.redirect(/login);}next(); }function checkNotLogin(req, res, next) {if (req.session.user) {req.flash(error, 已登录!); res.redirect(back);//返回之前的页面}next(); }checkNotLogin 和 checkLogin 用来检测是否登陆并通过 next() 转移控制权检测到未登录则跳转到登录页检测到已登录则跳转到前一个页面。 最终 index.js 代码如下 var crypto require(crypto),User require(../models/user.js);module.exports function(app) {app.get(/, function (req, res) {res.render(index, {title: 主页,user: req.session.user,success: req.flash(success).toString(),error: req.flash(error).toString()});});app.get(/reg, checkNotLogin);app.get(/reg, function (req, res) {res.render(reg, {title: 注册,user: req.session.user,success: req.flash(success).toString(),error: req.flash(error).toString()});});app.post(/reg, checkNotLogin);app.post(/reg, function (req, res) {var name req.body.name,password req.body.password,password_re req.body[password-repeat];if (password_re ! password) {req.flash(error, 两次输入的密码不一致!); return res.redirect(/reg);}var md5 crypto.createHash(md5),password md5.update(req.body.password).digest(hex);var newUser new User({name: req.body.name,password: password,email: req.body.email});User.get(newUser.name, function (err, user) {if (user) {req.flash(error, 用户已存在!);return res.redirect(/reg);}newUser.save(function (err, user) {if (err) {req.flash(error, err);return res.redirect(/reg);}req.session.user user;req.flash(success, 注册成功!);res.redirect(/);});});});app.get(/login, checkNotLogin);app.get(/login, function (req, res) {res.render(login, {title: 登录,user: req.session.user,success: req.flash(success).toString(),error: req.flash(error).toString()}); });app.post(/login, checkNotLogin);app.post(/login, function (req, res) {var md5 crypto.createHash(md5),password md5.update(req.body.password).digest(hex);User.get(req.body.name, function (err, user) {if (!user) {req.flash(error, 用户不存在!); return res.redirect(/login);}if (user.password ! password) {req.flash(error, 密码错误!); return res.redirect(/login);}req.session.user user;req.flash(success, 登陆成功!);res.redirect(/);});});app.get(/post, checkLogin);app.get(/post, function (req, res) {res.render(post, {title: 发表,user: req.session.user,success: req.flash(success).toString(),error: req.flash(error).toString()});});app.post(/post, checkLogin);app.post(/post, function (req, res) {});app.get(/logout, checkLogin);app.get(/logout, function (req, res) {req.session.user null;req.flash(success, 登出成功!);res.redirect(/);});function checkLogin(req, res, next) {if (!req.session.user) {req.flash(error, 未登录!); res.redirect(/login);}next();}function checkNotLogin(req, res, next) {if (req.session.user) {req.flash(error, 已登录!); res.redirect(back);}next();} };注意为了维护用户状态和 flash 的通知功能我们给每个 ejs 模版文件传入了以下三个值 user: req.session.user, success: req.flash(success).toString(), error: req.flash(error).toString()发表文章 现在我们的博客已经具备了用户注册、登陆、页面权限控制的功能接下来我们完成博客最核心的部分——发表文章。在这一节我们将会实现发表文章的功能完成整个博客的设计。 页面设计 我们先来完成发表页的页面设计。在 views 文件夹下新建 post.ejs 添加如下代码 %- include header % form methodpost标题br /input typetext nametitle /br /正文br /textarea namepost rows20 cols100/textareabr /input typesubmit value发表 / /form %- include footer %文章模型 仿照用户模型我们将文章模型命名为 Post 对象它拥有与 User 相似的接口分别是 Post.get 和 Post.prototype.save 。Post.get 的功能是从数据库中获取文章可以按指定用户获取也可以获取全部的内容。Post.prototype.save 是 Post 对象原型的方法用来将文章保存到数据库。 在 models 文件夹下新建 post.js 添加如下代码 var mongodb require(./db);function Post(name, title, post) {this.name name;this.title title;this.post post; }module.exports Post;//存储一篇文章及其相关信息 Post.prototype.save function(callback) {var date new Date();//存储各种时间格式方便以后扩展var time {date: date,year : date.getFullYear(),month : date.getFullYear() - (date.getMonth() 1),day : date.getFullYear() - (date.getMonth() 1) - date.getDate(),minute : date.getFullYear() - (date.getMonth() 1) - date.getDate() date.getHours() : (date.getMinutes() 10 ? 0 date.getMinutes() : date.getMinutes()) }//要存入数据库的文档var post {name: this.name,time: time,title: this.title,post: this.post};//打开数据库mongodb.open(function (err, db) {if (err) {return callback(err);}//读取 posts 集合db.collection(posts, function (err, collection) {if (err) {mongodb.close();return callback(err);}//将文档插入 posts 集合collection.insert(post, {safe: true}, function (err) {mongodb.close();if (err) {return callback(err);//失败返回 err}callback(null);//返回 err 为 null});});}); };//读取文章及其相关信息 Post.get function(name, callback) {//打开数据库mongodb.open(function (err, db) {if (err) {return callback(err);}//读取 posts 集合db.collection(posts, function(err, collection) {if (err) {mongodb.close();return callback(err);}var query {};if (name) {query.name name;}//根据 query 对象查询文章collection.find(query).sort({time: -1}).toArray(function (err, docs) {mongodb.close();if (err) {return callback(err);//失败返回 err}callback(null, docs);//成功以数组形式返回查询的结果});});}); };发表响应 接下来我们给发表文章注册响应打开 index.js 在 User require(../models/user.js) 后添加一行代码 Post require(../models/post.js);修改 app.post(/post) 如下 app.post(/post, checkLogin); app.post(/post, function (req, res) {var currentUser req.session.user,post new Post(currentUser.name, req.body.title, req.body.post);post.save(function (err) {if (err) {req.flash(error, err); return res.redirect(/);}req.flash(success, 发布成功!);res.redirect(/);//发表成功跳转到主页}); });最后我们修改 index.ejs 让主页右侧显示发表过的文章及其相关信息。 打开 index.ejs 修改如下 %- include header % % posts.forEach(function (post, index) { %ph2a href#% post.title %/a/h2/pp classinfo作者a href#% post.name %/a | 日期% post.time.minute %/pp%- post.post %/p % }) % %- include footer %打开 index.js 修改 app.get(/) 如下 app.get(/, function (req, res) {Post.get(null, function (err, posts) {if (err) {posts [];} res.render(index, {title: 主页,user: req.session.user,posts: posts,success: req.flash(success).toString(),error: req.flash(error).toString()});}); });至此我们的博客就建成了。 运行 启动mongodb.bat 和 启动app.bat 启动我们的博客发表一篇博文如下 此时查看一下数据库如图所示 TipsRobomongo 是一个基于 Shell 的跨平台开源 MongoDB 管理工具。嵌入了 JavaScript 引擎和 MongoDB mongo 。只要你会使用 mongo shell 你就会使用 Robomongo它提供语法高亮、自动完成、差别视图等。 以 Windows 下为例下载安装 Robomongo 。运行我们的博客注册一个用户并发表几篇文章初次打开 Robomongo 点击 Create 创建一个名为 blog 名字自定的数据库链接默认监听 localhost:27017点击 Connect 就连接到数据库了。如图所示 转载于:https://www.cnblogs.com/phpliu/p/3443853.html
http://www.yutouwan.com/news/71236/

相关文章:

  • 比较出名做耐克的网站怎么找wordpress博客
  • 网站怎么自己做中国网络安全厂商排名
  • 电商网站首页设计如何提升网站搜索排名
  • 网站改版页面不收录建设行政主管部门政务网站
  • 不收费的企业查询网站免费下载android
  • 长沙做网站找谁wordpress音乐美化
  • 大学生做网站步骤如何建立一个网站的快捷方式
  • 旅游网站图片网站有几个后台
  • html网站的直播怎么做的品牌策划 品牌年度服务
  • 网站关键字 优帮云广元市规划和建设局网站
  • 网站建设归工商局管还是工信局管大连网站制作案例
  • 深圳 网站托管免费企业网站模板 php
  • 网站开发公司杭州网站建设网站左侧 导航
  • 上海市建设安全协会网站孟 侠厦门建设局投诉电话
  • led高端网站建设潍坊专业汽车贴膜
  • 舟山网站建设制作thinkphp cms开源系统
  • 网站开发建设推荐用书app维护费用一般多少钱
  • 网站页面报价怎样做外贸网站推广
  • 建筑效果图网站推荐免费网站制作作业
  • 蓝色风格的网站株洲做网站多少钱
  • 小城镇建设投稿网站赣州人才网招聘网
  • 网站建设合同印花税大气自适应网站源码
  • 佛山市网站开发win7怎么做网站映射
  • 北京网站建设公司桂林小程序制作
  • 做网站要会写什么软件购物网站数据分析
  • 智能自助建站系统源码wordpress 创建文章
  • 网站架构制作c to c网站开发
  • 济南建设网站平台wordpress cms 教程
  • 网站模版 源码之家吉林网站建设吉林
  • 无形资产 网站开发国内一线网站设计公司