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

 

 

posted @ 2020-05-15 21:23  B216三个👎👎  阅读(254)  评论(0)    收藏  举报