项目作者: liyuechun

项目描述 :
全栈部落
高级语言: JavaScript
项目地址: git://github.com/liyuechun/nodetest1.git
创建时间: 2017-07-14T02:00:44Z
项目社区:https://github.com/liyuechun/nodetest1

开源协议:

下载


60分钟学会使用Node.js+Express+Ejs+mongoDB

本文出自从零到壹全栈部落

第1部分 – 15分钟安装

本文改编自THE DEAD-SIMPLE STEP-BY-STEP GUIDE FOR FRONT-END DEVELOPERS TO GETTING UP AND RUNNING WITH NODE.JS, EXPRESS, JADE, AND MONGODB

  • 第1步 - 环境安装

请直接移步Node.js官网,如下图所示,直接点击最新版下载并进行安装。

Node.js安装完毕后,打开终端,在终端分别输入如下命令,检测是否安装成功。

  1. Last login: Tue Jun 27 09:19:38 on console
  2. liyuechun:~ yuechunli$ node -v
  3. v8.1.3
  4. liyuechun:~ yuechunli$ npm -v
  5. 5.0.3
  6. liyuechun:~ yuechunli$

如果能够正确显示node和npm的版本,说明Node.js安装成功。

  • 第2步 - 安装Express
  1. Last login: Mon Jul 10 11:14:16 on ttys001
  2. liyuechun:~ yuechunli$ npm install -g express
  3. + express@4.15.3
  4. added 42 packages in 7.337s
  5. liyuechun:~ yuechunli$
  • 第3步 - 创建一个Express项目

我们准备使用ExpressEjs,这不是用来做CSS预处理的。我们会手写一些CSS。我们要用Ejs或者其它的模板引擎来处理Node和Express的数据。如果你会HTML的话,Ejs并不难。只要记住你需要集中精神,否则很容易出错。

  1. liyuechun:Desktop yuechunli$ pwd
  2. /Users/liyuechun/Desktop
  3. liyuechun:Desktop yuechunli$ mkdir 60MINUTES
  4. liyuechun:Desktop yuechunli$ cd 60MINUTES/
  5. bogon:60MINUTES yuechunli$ express -e nodetest1
  6. warning: option `--ejs' has been renamed to `--view=ejs'
  7. create : nodetest1
  8. create : nodetest1/package.json
  9. create : nodetest1/app.js
  10. create : nodetest1/public
  11. create : nodetest1/views
  12. create : nodetest1/views/index.ejs
  13. create : nodetest1/views/error.ejs
  14. create : nodetest1/routes
  15. create : nodetest1/routes/index.js
  16. create : nodetest1/routes/users.js
  17. create : nodetest1/bin
  18. create : nodetest1/bin/www
  19. create : nodetest1/public/javascripts
  20. create : nodetest1/public/stylesheets
  21. create : nodetest1/public/stylesheets/style.css
  22. install dependencies:
  23. $ cd nodetest1 && npm install
  24. run the app:
  25. $ DEBUG=nodetest1:* npm start
  26. create : nodetest1/public/images
  27. bogon:60MINUTES yuechunli$

VSCode打开,项目结构如下:

  • 第4步 - 编辑依赖项

好了,我们现在有一些基本项目结构,但是还没完。你会注意到express的安装过程在你的nodetest1目录里创建了一个叫package.json的文件,用文本编辑器打开这个文件,它应该是长这样的:

  1. {
  2. "name": "nodetest1",
  3. "version": "0.0.0",
  4. "private": true,
  5. "scripts": {
  6. "start": "node ./bin/www"
  7. },
  8. "dependencies": {
  9. "body-parser": "~1.17.1",
  10. "cookie-parser": "~1.4.3",
  11. "debug": "~2.6.3",
  12. "ejs": "~2.5.6",
  13. "express": "~4.15.2",
  14. "morgan": "~1.8.1",
  15. "serve-favicon": "~2.4.2"
  16. }
  17. }

这是一个标准的JSON格式文件,表明了我们应用的依赖。我们需要添加一点东西。比如对mongodb和Monk的调用。把dependencies部分改成这样:

  1. {
  2. "name": "nodetest1",
  3. "version": "0.0.0",
  4. "private": true,
  5. "scripts": {
  6. "start": "node ./bin/www"
  7. },
  8. "dependencies": {
  9. "body-parser": "~1.17.1",
  10. "cookie-parser": "~1.4.3",
  11. "debug": "~2.6.3",
  12. "ejs": "~2.5.6",
  13. "express": "~4.15.2",
  14. "morgan": "~1.8.1",
  15. "serve-favicon": "~2.4.2",
  16. "mongodb": "*",
  17. "monk": "*"
  18. }
  19. }
  • 第5步 – 安装依赖

现在我们定义好了项目的依赖项。*号会告诉NPM“安装最新版本”。回到命令行窗口,进入nodetest1目录,输入:

  1. bogon:nodetest1 yuechunli$ ls
  2. app.js package.json routes
  3. bin public views
  4. bogon:nodetest1 yuechunli$ npm install
  5. npm notice created a lockfile as package-lock.json. You should commit this file.
  6. added 80 packages in 4.563s
  7. bogon:nodetest1 yuechunli$ npm start
  8. > nodetest1@0.0.0 start /Users/liyuechun/Desktop/60MINUTES/nodetest1
  9. > node ./bin/www
  10. Express server listening on port 3000...
  11. GET / 200 13.288 ms - 207
  12. GET /stylesheets/style.css 200 3.295 ms - 111
  13. GET /favicon.ico 404 1.757 ms - 1136

浏览器输入http://127.0.0.1:3000,效果图如下:

第2部分 – 好了,我们来写“Hello, World!”吧

  • 查阅app.js源码
  1. var express = require('express');
  2. var path = require('path');
  3. var favicon = require('serve-favicon');
  4. var logger = require('morgan');
  5. var cookieParser = require('cookie-parser');
  6. var bodyParser = require('body-parser');
  7. var index = require('./routes/index');
  8. var users = require('./routes/users');
  9. var app = express();
  10. // view engine setup
  11. app.set('views', path.join(__dirname, 'views'));
  12. app.set('view engine', 'ejs');
  13. // uncomment after placing your favicon in /public
  14. app.use(logger('dev'));
  15. app.use(bodyParser.json());
  16. app.use(bodyParser.urlencoded({ extended: false }));
  17. app.use(cookieParser());
  18. app.use(express.static(path.join(__dirname, 'public')));
  19. app.use('/', index);
  20. app.use('/users', users);
  21. // catch 404 and forward to error handler
  22. app.use(function(req, res, next) {
  23. var err = new Error('Not Found');
  24. err.status = 404;
  25. next(err);
  26. });
  27. // error handler
  28. app.use(function(err, req, res, next) {
  29. // set locals, only providing error in development
  30. res.locals.message = err.message;
  31. res.locals.error = req.app.get('env') === 'development' ? err : {};
  32. // render the error page
  33. res.status(err.status || 500);
  34. res.render('error');
  35. });
  36. console.log("Express server listening on port 3000...");
  37. module.exports = app;
  • app.js中添加代码

现在,我们写点有用的。我们不会直接在我们的index页面里写“Hello World!”,我们借这个机会学习一下如何使用route路由,同时学习一下Ejs引擎是如何工作的。在上面的app.js文件中添加如下两行代码:

  • 创建helloworld.js文件

内容如下:

  1. var express = require('express');
  2. var router = express.Router();
  3. /* GET HelloWorld page. */
  4. router.get('/', function(req, res, next) {
  5. res.render('helloworld', { title: 'HelloWorld' });
  6. });
  7. module.exports = router;
  • 创建helloworld.ejs文件

内容如下:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title><%= title %></title>
  5. <link rel='stylesheet' href='/stylesheets/style.css' />
  6. </head>
  7. <body>
  8. <h1><%= title %></h1>
  9. </body>
  10. </html>
  • 运行程序
    npm start启动服务器,然后在浏览器打开http://localhost:3000/helloworld,应该能看到这个漂亮的界面了:

  • ejs⚠️去除

如上图所示,在VSCode中使用ejs代码会出现语法不识别的问题,启动VSCode,通过快捷键⌘+P快速打开窗口,将如下代码拷贝粘贴到里面,回车安装插件,然后重启即可。

  1. ext install ejs-language-support

EJS Language Support

扫码申请加入全栈部落

第3部分 – 创建数据库并读取数据

  • 第1步 - 更新HomeBrew
  1. Last login: Wed Jul 12 09:27:06 on ttys000
  2. liyuechun:~ yuechunli$ brew update
  3. Updated 1 tap (homebrew/core).
  4. ==> Updated Formulae
  5. radare2
  • 第2步 – 安装Mongodb
  1. liyuechun:~ yuechunli$ brew install mongodb
  2. ==> Downloading https://homebrew.bintray.com/bottles/mongodb-3.4.6.sierra.bottle
  3. Already downloaded: /Users/liyuechun/Library/Caches/Homebrew/mongodb-3.4.6.sierra.bottle.tar.gz
  4. ==> Pouring mongodb-3.4.6.sierra.bottle.tar.gz
  5. ==> Using the sandbox
  6. ==> Caveats
  7. To have launchd start mongodb now and restart at login:
  8. brew services start mongodb
  9. Or, if you don't want/need a background service you can just run:
  10. mongod --config /usr/local/etc/mongod.conf
  11. ==> Summary
  12. 🍺 /usr/local/Cellar/mongodb/3.4.6: 18 files, 266.9MB
  • 第3步 - 配置环境环境变量
  1. liyuechun:~ yuechunli$ echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
  • 第4步 - 创建数据库路径
  1. liyuechun:~ yuechunli$ mkdir -p /data/db
  • 第5步 - 启动MongoDb(安装成功后命令行有提示)
  1. liyuechun:~ yuechunli$ mongod --config /usr/local/etc/mongod.conf
  • 第6步 - 连接到mongo
  1. Last login: Wed Jul 12 11:00:21 on ttys000
  2. liyuechun:~ yuechunli$ mongo
  3. MongoDB shell version v3.4.6
  4. connecting to: mongodb://127.0.0.1:27017
  5. MongoDB server version: 3.4.6
  6. > 1+1
  7. 2
  8. >
  • 第7步 - 浏览器访问http://127.0.0.1:27017/

  • 第8步 - 创建数据库

use nodetest1这个命令,只有我们插入数据时,才会真正创建数据库。

  1. Last login: Wed Jul 12 11:35:52 on ttys001
  2. liyuechun:~ yuechunli$ mongo
  3. MongoDB shell version v3.4.6
  4. connecting to: mongodb://127.0.0.1:27017
  5. MongoDB server version: 3.4.6
  6. > use nodetest1
  7. switched to db nodetest1
  8. >
  • 第9步 - 添加一些数据

我最喜欢的MongoDB的特性就是它使用JSON作为数据结构,这就意味着我们对此非常的熟悉。如果你不熟悉JSON,先去读点相关资料吧,这超出了本教程的范围。

我们添加一些数据到collection中。在这个教程里,我们只有一个简单的数据库,username和email两个字段。我们的数据看起来是这个样子的:

  1. {
  2. "_id" : 1234,
  3. "username" : "liyuechun",
  4. "email" : "liyuechun@cldy.org"
  5. }

你可以创建你自己的_id字段的值,不过我觉得最好还是让mongo来做这件事。它会为每一条记录创建一个唯一的值。我们看看它是怎么工作的。在mongo的窗口中,输入:

  1. > db.usercollection.insert({"username" : "liyuechun", "email" : "liyuechun@cldy.org" })
  2. WriteResult({ "nInserted" : 1 })
  3. >

重要提示:db就是我们上面创建的nodetest1数据库,就是我们的collection,相当于一张数据表。注意我们不需要提前创建这个collection,它会在第一次使用的时候自动创建。好了,按下回车。

  • 第10步 - 数据库查询
  1. > db.usercollection.find().pretty()
  2. {
  3. "_id" : ObjectId("59659d8fbd3dbae3899471c2"),
  4. "username" : "liyuechun",
  5. "email" : "liyuechun@cldy.org"
  6. }
  7. >

当然,你得到ObjectID应该是不一样的,mongo会自动生成一个。如果你以前使用过JSON接口的服务,现在是不是会觉得,哇,在web里调用这个应该很简单吧!嗯,你说对了。

提示:作为正式服务,你应该不希望所有的数据都存在最顶层。关于mongodb数据结构的设计,多看看Google吧。

现在我们有了一条数据,我们多添加点吧。

  1. > db.usercollection.insert(
  2. [
  3. {"username":"yanan","email":"yanan@cldy.org"},
  4. {"username":"fujinliang","email":"fujinliang@cldy.org"},
  5. {"username":"shenpingping","email":"shenpingping@cldy.org"}
  6. ])
  7. BulkWriteResult({
  8. "writeErrors" : [ ],
  9. "writeConcernErrors" : [ ],
  10. "nInserted" : 3,
  11. "nUpserted" : 0,
  12. "nMatched" : 0,
  13. "nModified" : 0,
  14. "nRemoved" : 0,
  15. "upserted" : [ ]
  16. })
  17. > db.usercollection.find().pretty()
  18. {
  19. "_id" : ObjectId("59659d8fbd3dbae3899471c2"),
  20. "username" : "liyuechun",
  21. "email" : "liyuechun@cldy.org"
  22. }
  23. {
  24. "_id" : ObjectId("59659ffebd3dbae3899471c3"),
  25. "username" : "yanan",
  26. "email" : "yanan@cldy.org"
  27. }
  28. {
  29. "_id" : ObjectId("59659ffebd3dbae3899471c4"),
  30. "username" : "fujinliang",
  31. "email" : "fujinliang@cldy.org"
  32. }
  33. {
  34. "_id" : ObjectId("59659ffebd3dbae3899471c5"),
  35. "username" : "shenpingping",
  36. "email" : "shenpingping@cldy.org"
  37. }
  38. >

第11步 – 把mongo连接到node

现在我们来建立一个页面,把数据库里的记录显示成一个漂亮的表格。这是我们准备生成的HTML内容:

  1. <ul>
  2. <li><a href="mailto:liyuechun@cldy.org">liyuechun</a></li>
  3. <li><a href="mailto:yanan@testdomain.com">yanan</a></li>
  4. <li><a href="mailto:fujinliang@testdomain.com">fujinliang</a></li>
  5. <li><a href="mailto:shenpingping@testdomain.com">shenpingping</a></li>
  6. </ul>

打开nodetest1项目的app.js,现在接着往下看:

  1. var index = require('./routes/index');
  2. var users = require('./routes/users');
  3. var helloworld = require('./routes/helloworld');

下面添加一行:

  1. var userlist = require('./routes/userlist');

继续,找到下面代码的位置:

  1. app.use('/', index);
  2. app.use('/users', users);
  3. app.use('/helloworld', helloworld);

下面添加一行:

  1. app.use('/userlist', userlist);

第12步 – 创建 userlist.js 路由和 userlist.ejs 视图文件

如下图所示:

  • userlist.js内容如下:
  1. var express = require('express');
  2. var router = express.Router();
  3. /**
  4. * 这几行会告诉app我们需要连接MongoDB,我们用Monk来负责这个连接,我们数据库位置是localhost:27017/nodetest1。注意27017是mongodb的默认端口,如果因为某些原因你修改了端口,记录这里也要跟着改。
  5. */
  6. var mongo = require('mongodb');
  7. var monk = require('monk');
  8. var db = monk('127.0.0.1:27017/nodetest1');
  9. /* GET userlist page. */
  10. router.get('/', function (req, res, next) {
  11. var collection = db.get('usercollection');
  12. collection.find({}, {}, function (e, docs) {
  13. res.render('userlist', {"userlist": docs});
  14. });
  15. });
  16. module.exports = router;
  • userlist.ejs内容如下:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>USERLIST</title>
  5. <link rel='stylesheet' href='/stylesheets/style.css' />
  6. </head>
  7. <body>
  8. <h1>Userlist</h1>
  9. <ul>
  10. <%
  11. for(var i in userlist){
  12. %>
  13. <li>
  14. <a href="mailto:<%=userlist[i].email%>">
  15. <%=userlist[i].username%>
  16. </a>
  17. </li>
  18. <% } %>
  19. </ul>
  20. </body>
  21. </html>

保存文件,重启node服务器。希望你还记得怎么重启。打开浏览器,访问http://localhost:3000/userlist,你应该能看到这样的界面:

现在你从数据库里取到了数据并且显示到了网页上。太棒了。

第4部分 – 终于到了:往数据库里写入数据

往数据库里写入数据也不是很困难。我们需要一个route来接收POST请求而不是GET。我们可以使用Ajax,这是我最常用的方式。不过那可能需要另外一篇教程了,所以这里我们还是用最原始的post手段。当然,要记住,如果你愿意,用ajax并不难。

  • 第1步 – 建立你的数据输入页面

这里我们需要快一点:建立两个丑陋的不加样式的文本框和一个提交按钮。像上面一样,我们从app.use()开始。打开app.js找到下面的代码:

  1. var index = require('./routes/index');
  2. var users = require('./routes/users');
  3. var helloworld = require('./routes/helloworld');
  4. var userlist = require('./routes/userlist');

在下面加上:

  1. var newuser = require('./routes/newuser');

再找到下面的代码:

  1. app.use('/', index);
  2. app.use('/users', users);
  3. app.use('/helloworld', helloworld);
  4. app.use('/userlist', userlist);

在下面加上:

  1. app.use('/newuser', newuser);

routs文件夹中创建newuser.js文件,内容如下:

  1. var express = require('express');
  2. var router = express.Router();
  3. /* GET users listing. */
  4. router.get('/', function(req, res, next) {
  5. res.render('newuser', { title: 'Add New User' });
  6. });
  7. module.exports = router;

views文件夹中创建newuser.ejs文件,内容如下:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Add User</title>
  5. <link rel="stylesheet" href="/stylesheets/style.css" />
  6. </head>
  7. <body>
  8. <h1>
  9. <%= title %>
  10. </h1>
  11. <form name="adduser" method="post" action="/adduser">
  12. <input type="text" placeholder="username" name="username" />
  13. <input type="text" placeholder="useremail" name="useremail" />
  14. <input type="submit" value="submit" />
  15. </form>
  16. </body>
  17. </html>

这里我们创建一个form,method是post,action是adducer。简单明了。下面我们定义了两个输入框和一个提交按钮。启动服务器,浏览器打开http://localhost:3000/newuser效果图如下:

点提交按钮,会出现如下错误,我们来修正错误。

  1. Not Found
  2. 404
  3. Error: Not Found
  4. at /Users/liyuechun/Desktop/60MINUTES/nodetest1/app.js:36:13
  5. at Layer.handle [as handle_request] (/Users/liyuechun/Desktop/60MINUTES/nodetest1/node_modules/express/lib/router/layer.js:95:5)
  6. at trim_prefix (/Users/liyuechun/Desktop/60MINUTES/nodetest1/node_modules/express/lib/router/index.js:317:13)
  7. at /Users/liyuechun/Desktop/60MINUTES/nodetest1/node_modules/express/lib/router/index.js:284:7
  8. at Function.process_params (/Users/liyuechun/Desktop/60MINUTES/nodetest1/node_modules/express/lib/router/index.js:335:12)
  9. at next (/Users/liyuechun/Desktop/60MINUTES/nodetest1/node_modules/express/lib/router/index.js:275:10)
  10. at /Users/liyuechun/Desktop/60MINUTES/nodetest1/node_modules/express/lib/router/index.js:635:15
  11. at next (/Users/liyuechun/Desktop/60MINUTES/nodetest1/node_modules/express/lib/router/index.js:260:14)
  12. at Function.handle (/Users/liyuechun/Desktop/60MINUTES/nodetest1/node_modules/express/lib/router/index.js:174:3)
  13. at router (/Users/liyuechun/Desktop/60MINUTES/nodetest1/node_modules/express/lib/router/index.js:47:12)
  • 第2步 – 创建你的数据库处理函数

打开app.js文件,找到下面的代码:

  1. var index = require('./routes/index');
  2. var users = require('./routes/users');
  3. var helloworld = require('./routes/helloworld');
  4. var userlist = require('./routes/userlist');
  5. var newuser = require('./routes/newuser');

在下面添加一行:

  1. var adduser = require('./routes/adduser');

再次找到下面的代码:

  1. app.use('/', index);
  2. app.use('/users', users);
  3. app.use('/helloworld', helloworld);
  4. app.use('/userlist', userlist);
  5. app.use('/newuser', newuser);

在下面添加一行:

  1. app.use('/adduser', adduser);

接下来在routes文件夹下面创建adduser.js文件,内容如下:

  1. var express = require('express');
  2. var router = express.Router();
  3. // New Code
  4. var mongo = require('mongodb');
  5. var monk = require('monk');
  6. var db = monk('localhost:27017/nodetest1');
  7. /* POST userlist page. */
  8. router.post('/', function (req, res, next) {
  9. // Get our form values. These rely on the "name" attributes
  10. var userName = req.body.username;
  11. var userEmail = req.body.useremail;
  12. // Set our collection
  13. var collection = db.get('usercollection');
  14. // Submit to the DB
  15. collection.insert({
  16. "username": userName,
  17. "email": userEmail
  18. }, function (err, doc) {
  19. if (err) {
  20. // If it failed, return error
  21. res.send("There was a problem adding the information to the database.");
  22. } else {
  23. // If it worked, set the header so the address bar doesn't still say /adduser
  24. res.location("userlist");
  25. // And forward to success page
  26. res.redirect("userlist");
  27. }
  28. });
  29. });
  30. module.exports = router;

上面的代码是通过post请求拿到表单中的usernameemail,然后重定向到userlist页面。

启动服务器,在浏览器中打开http://localhost:3000/newuser,效果如下所示:

在里面输入用户名和邮箱,就会跳转到userlist页面,如下面所示:

现在我们正式的完成了使用Node.js,Exress,Ejs读取和写入Mongodb数据库,我们已经是牛X的程序员了。

恭喜你,真的。如果你认真的看完了这篇教程,并且很认真的学习而不只是复制代码,你应该对routes, views,读数据,写入数据有了完整的概念。这是你用来开发任何其它完整的Web网站所需要的一切知识点!不管你怎么想,我觉得这真挺酷的。

扫码申请加入全栈部落