Express+Mongodb二

Express详细分析

Express文件目录

1
app.js

启动文件,或者说入口文件

1
package.json

存储着工程的信息及模块依赖,当在 dependencies 中添加依赖的模块时,
运行 npm install ,npm 会检查当前目录下的 package.json,并自动安装所有指定的模块

1
node_modules

存放 package.json 中安装的模块,当你在 package.json 添加依赖的模块并安装后,存放在这个文件夹下

1
public

存放 image、css、js 等文件

1
routes

存放路由文件

1
views

存放视图文件或者说模板文件

1
bin

存放可执行文件

app.js

1
require()

通过 require() 加载了 express、path 等模块,以及 routes 文件夹下的 index.js 和 user.js 路由文件

1
var app = express()

生成一个 express 实例 app

1
app.set('view', path.join(dirname, 'views'))

设置 views 文件夹为存放视图文件的目录,即存放模板文件的地方,dirname 为全局变量,存储当前正在执行的脚本所在的目录

1
2
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

设置视图模板引擎为 ejs

1
app.use(favicon(dirname + '/public/favicon.ico'))

设置 /public/favicon.ico 为 favicon 图标

1
app.use(logger('dev'))

加载日志中间件

1
app.use(bodyParser.json())

加载解析 json 的中间件

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

加载解析 urlencoded 请求体的中间件

1
app.use(cookieParser())

加载解析 cookie 的中间件

1
app.use(express.static(path.join(dirname, 'public')))

设置 public 文件夹为存放静态文件的目录

1
2
3
app.use('/', routes)和app.use('/users', users)
http://localhost:4000/test
http://localhost:4000/users/test

一级路由控制

1
2
3
4
5
6
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});

捕获404错误,并转发到错误处理器

1
2
3
4
5
6
7
8
9
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}

开发环境下的错误处理器,将错误信息渲染 error 模板并显示到浏览器中

1
2
3
4
5
6
7
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});

生产环境下的错误处理器,将错误信息渲染 error 模板并显示到浏览器中

1
module.exports = app

导出 app 实例供其他模板调用

bin/www

1
#!/usr/bin/env node

表明这是一个 node 可执行文件

1
var debug = require('debug')('blog:server')

引入 debug 模块,打印调试日志

1
var app = require('../app')

引入我们上面导出的 app 实例

1
2
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

设置端口号

1
var server = http.createServer(app)

创建 HTTP 服务

1
2
3
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

启动工程并监听 3000 端口

routes/index.js

1
2
3
4
5
6
7
8
9
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;

这个代码的意思是,先导入 express 模块,然后生成一个路由实例用来捕获访问主页的 GET 请求,导出这个路由并在 app.js 中通过 app.use(‘/‘, routes) 加载。
这样,当访问主页时,就会调用 res.render(‘index’, {title: ‘Express’}) 渲染 views/index.ejs 模板并显示到浏览器中

views/index.ejs

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
</body>
</html>

在渲染模板时,我们传入了一个变量 title 值为 express 字符串,
模板引擎将所有 <%= title %> 替换为 express,然后将渲染后生成的html显示到浏览器中

ejs

ejs 是模板引擎的一种,也是我们这个教程中使用的模板引擎,因为它使用起来十分简单

使用模板引擎

1
2
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

express -e blog 只是初始化了一个使用 ejs 模板引擎的工程而已,
比如 node_modules 下添加了 ejs 模板,views 文件夹下有 index.ejs

res.render()

在 routes/index.js 中通过调用 res.render() 渲染模板,并将其产生的页面直接返回给客户端。
它接受两个参数,第一个是模板的名称,即 views 目录下的模板文件名,扩展名 .ejs 可选。
第二个参数是传递给模板的数据对象,用于模板翻译

views/index.ejs 中的代码

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
</body>
</html>

当我们 res.render(‘index’, {title: ‘Express’}); 时,
模板引擎会把 <%= title %> 替换成 Express,然后把替换成的页面显示给用户

渲染后生成的页面代码为

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<title>Express</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>Express</h1>
<p>Welcome to Express</p>
</body>
</html>

静态文件

1
app.use(express.static(path.join(__dirname, 'public')))

设置了静态文件目录为 public 文件夹,所以上面代码中的 href = ‘/stylesheets/style.css’
就相当于 href = ‘public/stylesheets/style.css’

ejs 的标签系统

1
2
3
<% code %>: JavaScript 代码。
<%= code %>: 显示替换过 HTML 特殊字符的内容。
<%- code %>: 显示原始 HTML 内容

<%= code %> 和 <%- code %> 的区别,当变量 code 为普通字符串时,两者没有区别。
当 code 比如为 <h1> hello </h1> 这种字符串时,<%= code %> 会原样输出 <h1> hello </h1>
而 <%- code %> 则会直接显示 H1 大小的 hello 字符串

ejs 的官网实例

The Data

1
supplies: ['mop', 'broom', 'duster']

The Template

1
2
3
4
5
<ul>
<% for(var i=0; i<supplies.length; i++) {%>
<li><%= supplies[i] %></li>
<% } %>
</ul>

The Result

1
2
3
4
5
<ul>
<li>mop</li>
<li>broom</li>
<li>duster</li>
</ul>

页面布局

index.ejs

1
2
3
<%- include a %>
hello,world!
<%- include b %>

a.ejs

1
this is a.ejs

b.ejs

1
this is b.ejs

最终 index.ejs 会显示

1
2
3
this is a.ejs
hello, world!
this is b.ejs