学习环境
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 install,npm 会检查当前目录下的 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?q=tobi+ferret
req.query.q
// => "tobi ferret"
// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
req.query.order
// => "desc"
req.query.shoe.color
// => "blue"
req.query.shoe.type
// => "converse"
req.body
// POST user[name]=tobi&user[email]=tobi@learnboost.com
req.body.user.name
// => "tobi"
req.body.user.email
// => "tobi@learnboost.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)**
// ?name=tobi
req.param('name')
// => "tobi"
// POST name=tobi
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
Welcome to
当我们 res.render('index', { title: 'Express' }); 时,模板引擎会把 替换成 Express,然后把替换后的页面显示给用户。
渲染后生成的页面代码为:
Express
Express
Welcome to Express
注意 :我们通过 app.use(express.static(path.join(__dirname, 'public'))) 设置了静态文静目录为 public 文件夹,所以上面代码中的 href='/stylesheets/style.css' 就相当于 href='public/stylesheets/style.css' 。
ejs 的标签系统非常简单,它只有以下三种标签:
:JavaScript 代码。
:显示替换过 HTML 特殊字符的内容。
:显示原始 HTML 内容。
注意 : 和 的区别,当变量 code 为普通字符串时,两者没有区别。当 code 比如为 hello 这种字符串时, 会原样输出 hello,而 则会显示 H1 大的 hello 字符串。
我们可以在 内使用 JavaScript 代码。下面是 ejs 的官方示例:
The Data
supplies: ['mop', 'broom', 'duster']
The Template
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com