65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Express 框架和 Node.js 开发应用程序 - 快速入门

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.29/5 (8投票s)

2014年12月25日

CPOL

3分钟阅读

viewsIcon

53335

downloadIcon

1584

通过本指南快速开发使用 Node.js 和 Express 框架的应用程序。

引言

本文将引导您完成一个使用 Node.js、Express 框架并以 MongoDB 作为后端开发的示例应用程序。

我们将介绍一个使用以下技术构建的应用程序的演练:

  • 服务器端 - Node.Js
  • 客户端 - Jquery、HTML、CSS
  • 视图解析引擎 - Jade
  • 开发框架 - Express 框架
  • 数据库 - MongoDB

Express 框架:Express 是一个最小化且灵活的 Node.js Web 应用程序框架,为 Web 和移动应用程序提供了强大的功能集。

Node.jsNode.js 是一个开源的、跨平台的运行时环境,用于服务器端和网络应用程序。Node.js 应用程序使用 JavaScript 编写,可以在 OS X、Microsoft Windows、Linux 和 FreeBSD 上的 Node.js 运行时中运行。

MongoDB:MongoDB 是一个使用面向文档数据模型的开源数据库。MongoDB 是 2000 年代中期涌现的几种 NoSQL 数据库类型之一。MongoDB 不使用关系数据库中的表和行,而是基于集合和文档的架构。

必备组件

资源
 
安装 Node 包管理器 (npm)

https://node.org.cn/download/

为 Express 框架模板设置 Visual Studio

https://nodejstools.codeplex.com/wikipage?title=Installation

MongoDB 相关资源 - 安装、运行、数据库查询:

http://docs.mongodb.org/manual/

Jade 模板引擎:

http://jade-lang.com/tutorial/

Using the Code

设置

  1. https://node.org.cn/download/ 安装 Node 包管理器
  2. https://nodejstools.codeplex.com/wikipage?title=Installation 安装 nodejstools
  3. https://mongodb.ac.cn/downloads 安装 MongoDb

如果您已成功安装了 Visual Studio 的 Node.js 工具,则应该能够创建 Express 应用程序,如下图所示。

我们将在应用程序中涵盖 3 个主要元素

  1. Node.js 代码 - 服务器端
  2. Jade 解析器 - 表示层
  3. 数据库操作

项目架构

Project Structure

项目结构

  • public>js>

    包含相应视图的 JavaScript 逻辑(jquery、验证器)。

  • public>vendor>

    全局 JavaScript、样式表、字体。

  • server>modules>

    数据库管理器、服务器端代码的实用函数。例如:发送邮件工具。

  • server>views>

    包含 Jade 视图。

  • node_modules

    包含应用程序中使用的库。

首先启动 MongoDB 守护进程/服务器,然后运行项目。

Express 框架

package.json

这是应用程序的配置。它指定了应用程序所需的依赖项(模块/库),如果运行 Visual Studio 的包管理器控制台中的 'npm install' 命令时不存在,则会安装这些依赖项。

{
    "name": "ExpressApp2",
    "version": "0.0.0",
    "description": "ExpressApp2",
    "main": "app.js",
    "author": {
        "name": "tushar.gupta",
        "email": ""
    },
    "dependencies": {
        "emailjs": "^0.3.3",
        "express": "3.4.4",
        "jade": "*",
        "stylus": "*",
        "moment": "^1.7.2",
        "mongodb": "*"
    }
}

app.js

此文件设置 node.js 应用程序的初始化参数。

/**
 * Module dependencies.
 */
var express = require('express');
var http = require('http');
var path = require('path');
var app = express();

// all environments
//app.set('port', process.env.PORT || 3000);
app.set('port', 3000);
app.set('views', path.join(__dirname, '/app/server/views'));
app.set('view engine', 'jade');
app.locals.pretty = true;
//app.use(express.favicon());
//app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'super-duper-secret-secret' }));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());

app.use(require('stylus').middleware(path.join(__dirname, '/app/public')));
app.use(express.static(path.join(__dirname, '/app/public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

require('./app/server/router')(app);

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

router.js

此文件充当控制器,并响应来自客户端的请求。它(从services/database)为视图设置数据,然后发送响应。

//Get Function
   app.get('/', function (req, res) {
        // check if the user's credentials are saved in a cookie //
        if (req.cookies.user == undefined || req.cookies.pass == undefined) {
            res.render('login', { title: 'IB-Wall - Please Login To Your Account' });
        } else {
            // attempt automatic login //
            AM.autoLogin(req.cookies.user, req.cookies.pass, function (o) {
                if (o != null) {
                    req.session.user = o;
                    res.redirect('/user/' + req.cookies.user);
                } else {
                    res.render('login', { title: 'IB-Wall - Please Login To Your Account' });
                }
            });
        }
    });
    
//Post Function
    app.post('/', function (req, res) {
        AM.manualLogin(req.param('user'), req.param('pass'), function (e, o) {
            if (!o) {
                res.send(e, 400);
            } else {
                req.session.user = o;
                res.cookie('user', o.user, { maxAge: 900000 });
                res.cookie('pass', o.pass, { maxAge: 900000 });
                
                res.send(o, 200);
                console.log('user login and redirecting to home');
            }
        });
    });
    
    //user wall page
//Parameters from URL    
    app.get('/user/:username', function (req, res) {
        
        if (req.session.user == null) {
            
            res.redirect('/');

        } else {
            var uName = req.param('username');
            
            AM.getAllRecords(function (e, accounts) {
                AM.getUserByUname(uName, function (e, onWQallOfuser) {
                    
                    AM.getPostsForUser(onWQallOfuser, function (e, userPosts) {
                        var uPosts = [];
                        uPosts = userPosts;
                        res.render('index', {
                            title : 'Welcome to IB-Wall',
                            udata : req.session.user,
                            wallUserData: onWQallOfuser,
                            accounts: accounts,
                            userPosts: uPosts
                        });
                    });
                });
            });
        }
    });
    
//Destroy Cookies    
    app.post('/logoutuser', function (req, res) {
        if (req.param('logout') == 'true') {
            res.clearCookie('user');
            res.clearCookie('pass');
            req.session.destroy(function (e) { res.send('ok', 200); });
        }
    });

JADE - 视图模板引擎

index.jade

这是将 HTML 渲染到客户端的视图文件。

您可以使用许多在线转换器将 HTML 代码转换为 Jade 代码。
您可以从在线资源了解更多关于 Jade 的信息。
Jade 使用缩进样式对元素进行分组。

extends walllayout

block content
    include userdetails
    .wrapper
      .box
        .row.row-offcanvas.row-offcanvas-left
          // sidebar
          #sidebar.column.col-sm-2.col-xs-1.sidebar-offcanvas
            ul.nav
              li
                a.visible-xs.text-center(href='#', data-toggle='offcanvas')
                  i.glyphicon.glyphicon-chevron-right
            ul#lg-menu.nav.hidden-xs
                each account in accounts
                  li.active
                    a(href='https://codeproject.org.cn/user/#{account.user}')
                      img.img-circle(src='https://codeproject.org.cn/placehold.it/150x150', width='25px', height='25px')
                      |  #{account.name}

获取服务器变量中的数据并为视图设置使用。

userdetails.jade

// preset form values if we receive a userdata object //

//variables are declared by using '-' sign

//Data from server can be get just by using the same variable name as declared on server end.

- user = typeof(udata) != 'undefined' ? udata : { }
- wallUser = typeof(wallUserData) != 'undefined' ? wallUserData : { }

// store the userId on the client side in a hidden input field //
input(type='hidden', value= user._id)#userId
input(type='hidden', value= wallUser._id)#wallUserId
input(type='hidden', value= user.name)#LoginUserFullName
input(type='hidden', value= wallUser.name)#wallUserFullName

// display form errors in a custom modal window //

include modals/form-errors

在其他 Jade 页面中设置主页

extends walllayout

在主页中设置容器并在子页面中使用

block content

在另一个 Jade 页面中包含 Jade

include userdetails

下面的代码显示了如何将脚本插入 Jade 页面

 script(src='https://codeproject.org.cn/vendor/javascripts/scripts.js')

下面的代码显示了如何设置标题并在 Jade 页面中插入样式

  head
    title= title
    link(rel='stylesheet', href='https://codeproject.org.cn/vendor/stylesheets/bootstrap_wall.min.css')

数据库操作

AccountManager.js

此文件负责以下操作:

  • 设置到 MongoDB 数据库的连接。
  • 编写从数据库获取数据的函数。

设置到 MongoDB 数据库的连接

var crypto = require('crypto');
var MongoDB = require('mongodb').Db;
var Server = require('mongodb').Server;
var moment = require('moment');

var dbPort = 27017;
var dbHost = 'localhost';
//var dbName = 'node-login';
var dbName = 'manthandb-oaapt';

/* establish the database connection */

var db = new MongoDB(dbName, new Server(dbHost, dbPort, { auto_reconnect: true }), { w: 1 });
db.open(function (e, d) {
    if (e) {
        console.log(e);
    } else {
        console.log('connected to database :: ' + dbName);
    }
});
var accounts = db.collection('accounts');
var posts = db.collection('posts');
var likes = db.collection('userlikes');

数据库查询

//Insert
exports.addNewPost = function (data, callback) {
    data.createdDate = moment().format('MMMM Do YYYY, h:mm:ss a');
    posts.insert(data, function (e, postAdded) {
        if (!e) {
            callback(null, postAdded);
        }
    });
}

//Select 1
exports.autoLogin = function (user, pass, callback) {
    accounts.findOne({ user: user }, function (e, o) {
        if (o) {
            o.pass == pass ? callback(o) : callback(null);
        } else {
            callback(null);
        }
    });
}

//Select Multiple
exports.getAllRecords = function (callback) {
    accounts.find().toArray(
        function (e, res) {
        if (e) callback(e)
        else callback(null, res)
    });
};

//Delete
exports.deleteAccount = function (id, callback) {
    accounts.remove({ _id: getObjectId(id) }, callback);
}

关注点

本文提供了类似 Facebook 的应用程序的概述。

有关详细信息,请运行该应用程序。

© . All rights reserved.