Express框架学习笔记
Express框架入门笔记
Express入门
node.js和npm已经安装,好像是在去年做微信小程序的时候?在此记录一下安装过程。
mkdir myapp cd myapp npm init//会要求输入一些配置项 npm install express --save //安装 Express 并将其保存到依赖列表

package name: 项目名称
version: 版本号
description: 对项目的描述
entry point: 项目的入口文件(默认为index.js也可自定义为app.js之类的)
test command: 项目启动的时候要用什么命令来执行脚本文件(默认为node app.js)
git repository: 如果要将项目上传到git中的话,就需要填写git的仓库地址
keywirds: 项目关键字
author: 作者的名字
license: 发行项目需要的证书
为方便之后扩展程序,直接使用express-generator 创建程序
npm install -g express-generator express -h

{content}nbsp;express -h
Usage: express [options] [dir]
Options:
-h, --help 输出使用方法
--version 输出版本号
-e, --ejs 添加对 ejs 模板引擎的支持
--hbs 添加对 handlebars 模板引擎的支持
--pug 添加对 pug 模板引擎的支持
-H, --hogan 添加对 hogan.js 模板引擎的支持
--no-view 创建不带视图引擎的项目
-v, --view <engine> 添加对视图引擎(view) <engine> 的支持 (ejs|hbs|hjs|jade|pug|twig|vash) (默认是 jade 模板引擎)
-c, --css <engine> 添加样式表引擎 <engine> 的支持 (less|stylus|compass|sass) (默认是普通的 css 文件)
--git 添加 .gitignore
-f, --force 强制在非空目录下创建
express --view=pug myapp cd myapp npm install set DEBUG=myapp:* & npm start//然后访问http://localhost:3000/
文档上对于路由的解释,大概就是通过实例+请求方法,指定对应路径做出相应反应。

express程序中常见方法
下面记录下一些(express和node.js的)内置方法的用法:
Node.js采用模块化结构,按照CommonJS规范定义和使用模块。模块与文件是一一对应关系,即加载一个模块,实际上就是加载对应的一个模块文件。
require命令用于指定加载模块,加载时可以省略脚本文件的后缀名。
var circle = require('./circle.js');
// 或者
var circle = require('./circle');
有时一个模块就是一个目录,包含多个文件,这时node就会在package.json中寻找main属性所指的入口文件,并包含之。
app.set(name, value)、app.get(name)
将设置项 name 的值设为 value
app.set('title', 'My Site');
app.get('title');
// => "My Site"
获取设置项 name 的值
app.get('title');
// => undefined
app.set('title', 'My Site');
app.get('title');
// => "My Site"
app.enable(name)、app.disable(name)、app.enabled(name)、app.disabled(name)
将设置项 name 的值设为 true
将设置项 name 的值设为 false.
检查设置项 name 是否已启用
检查设置项 name 是否已禁用
app.use([path],function)
使用函数function作用于path上(默认为'/'),app.user()定义的中间件优先级很重要,比如logger()中间件在响应中间件之后,则该相应不会被记录。
var express = require('express');
var app = express();
// 一个简单的 logger
app.use(function(req, res, next){
console.log('%s %s', req.method, req.url);
next();
});
// app.user(express.logger())
// 响应
app.use(function(req, res, next){
res.send('Hello World');
});
app.listen(3000);
映射文件:将public文件夹中的文件,以/static为前缀进行访问。这里使用中间件express.static()提供静态文件服务。
app.use('/static', express.static('public'))
app.use('/static', express.static(path.join(__dirname, 'public')))
//在其他文件夹启动该程序时,不能直接通过相对路径了,应使用绝对路径。
app.engine(ext, callback)
注册模板引擎的callback用来处理ext扩展名的文件,默认为根据文件扩展名require()
对应的模板引擎。使用consolidate.js调用各种引擎。
app.engine('jade', require('jade').__express);
app.engine('html', require('ejs').renderFile);
var engines = require('consolidate');
app.engine('haml', engines.haml);
app.engine('html', engines.hogan);
app.param([name], callback)
路由参数处理,用于校验路由参数或做出过滤,可以结合正则对参数进行校验。如果只传一个callback,相当于重写app.param()的API。
普通用法:
var app =express();
app.param(function(param, validator) {
return function (req, res, next, val) {
if (validator(val)) {
next();
}
else {
res.sendStatus(403);
}
}
})
app.param('id', function (candidate) {
return !isNaN(parseFloat(candidate)) && isFinite(candidate);
});
app.get('/user/:id', function (req, res) {
res.send('OK');
})
正则用法:
//express-parms
app.param(function(name, fn){
if (fn instanceof RegExp) {
return function(req, res, next, val){
var captures;
if (captures = fn.exec(String(val))) {
req.params[name] = captures;
next();
} else {
next('route');
}
}
}
});
app.param('id', /^\d+$/);
app.get('/user/:id', function(req, res){
res.send('user ' + req.params.id);
});
app.param('range', /^(\w+)\.\.(\w+)?$/);
app.get('/range/:range', function(req, res){
var range = req.params.range;
res.send('from ' + range[1] + ' to ' + range[2]);
});
app.method(path, [callback…], callback)
method指HTTP的请求方法,get,post等,path指被访问的路径,也可以使用正则进行匹配,回调函数允许有多个且优先级一致。也可以传入一个回调函数数组。
app.get('/', function(req, res){
res.send('hello world');
});
app.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){
var from = req.params[0];
var to = req.params[1] || 'HEAD';
res.send('commit range ' + from + '..' + to);
});
app.all(path, [callback…], callback)
和app.method()用法类似,但app.all()匹配所有HTTP方法,可以用来设置全局白名单函数。
app.all('/api/*', requireAuthentication);
//这样只要访问ip:port/api/*就都需要进行身份认证
app.locals()
app.locals对象是一个Javascript函数,执行的时候会把属性合并到自身,因此可以直接访问其定义的属性。
app.locals({
title: 'during',
email: 'a@qq.com'
});
app.locals.title
// => during
app.locals.email
// => 'a@qq.com'
电脑是不可以在其中定义Functions和Objects内置的属性,如定义属性name:
app.locals({name: 'oliver'});
app.locals.name
// => 返回 'app.locals' 而不是 'oliver' (app.locals 是一个函数 !)
// => 如果name变量用在一个模板里,发返回一个 ReferenceError
name, apply, bind, call, arguments, length, constructor等关键字被使用时,实际上app.locals.name返回的是函数app.locals()的名字。
app.render(view, [options], callback)
手册中没太看懂,查了几篇博文大致得出这个结论:view是渲染目标,渲染完成后通过callback回调返回一个view渲染之后的html,其中options是可选参数,包含了这个view需要用到的本地数据。res.render()底层就是通过调用app.render实现的,由于res.render提供多种便携功能,如把渲染得到的html文件直接发送给客户端,常常使用res.render()代替app.render。但是res.render不能直接使用本地变量。
app.render('email', function(err, html) {
// ...
});
app.render('email', {name:'during'}, function(err, html) {
// ...
});
email文件中的name将被渲染成during
app.routes
app.routes对象存储了所有被app.method定义的路由,通过这个对象可以动态的进行路由的创建和删除。
app.listen(number)
在给定的主机和端口上监听请求。app.listen(number)实际上是将创建http服务器的方法包装成快捷方法。
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};

参考链接及附录
Express.js API文档:https://www.ctolib.com/docs-Expressjs-c-ExpressJS3.html
node.js API文档:https://nodejs.org/dist/latest-v12.x/docs/api/
Express支持的模板引擎列表:https://github.com/tj/consolidate.js
--By Wander

浙公网安备 33010602011771号