Node.js之Express4.x

一、安装及项目建立

1.官网下载安装node.js(不提)
2.express4.x安装

$ npm install -g express-generator  
注意:4.x把命令行工具分离出来了,express-generator必须先全局安装,
如果需要安装指定版本: npm install -g express-generator@3.5.0

$ npm install express --save   
注意:express 没必要全局安装,但最好 安装的同时,进行保存,即 加上 --save.  此处 express 最好和 上面的 express-generator 版本一致

$ npm install  *** --save  
注意:其他模块的安装类似 express 模块,也可不全局安装,但最好 安装的同时,进行保存,即 加上 --save.

卸载模块使用: npm uninstall  express 

3.创建NodeJS项目

$ express --view=jade extest
参数:jade :是创建的项目模板  # 项目模板共有多种(常见的有): ejs,hbs,pug,jade,haml,....等,可使用$ express -h进行查看
     mytest:是项目名称

这里写图片描述

按照指示进入目录进行安装依赖:

$ cd extest && npm install   # 该句实际包含两条命令:进入项目 和 安装依赖包

启动:

npm start
注意:express 4.x 无法以 node app.js 为启动方式

客户端输入:localhost:3000,如果展示下面的形式,则表示安装成功。
这里写图片描述

二、项目介绍

1.目录结构
生成的目录结构如下图所示:
这里写图片描述
bin, 存放启动项目的脚本文件
node_modules, 存放所有的项目依赖库
public,静态文件(css,js,img)
routes,路由文件(MVC中的C,controller)
views,页面文件(相关模板)
package.json,项目依赖配置及开发者信息
app.js,应用核心配置文件
2.package.json配置文件
这里写图片描述
里面展示我们依赖配置的版本号,其中scripts属性是用于定义操作命令的,可以非常方便的增加启动命令,比如默认的start,用npm start代表执行node ./bin/www命令。
3.app.js核心开发文件
node开发的核心代码在这儿编写,中间枢纽。

//加载依赖库
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var logger = require('morgan');
//加载路由控制
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
///创建项目实例
var app = express();

// 定义jade模板引擎和模板文件位置
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// 定义日志和输出级别
app.use(logger('dev'));
//定义数据解析器
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
//定义cookie解析器
app.use(cookieParser());
//定义静态文件目录
app.use(express.static(path.join(__dirname, 'public')));
// 匹配路径和路由
app.use('/', indexRouter);
app.use('/users', usersRouter);

// 404错误处理
app.use(function(req, res, next) {
  next(createError(404));
});

// 开发环境,500错误处理
app.use(function(err, req, res, next) {
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  res.status(err.status || 500);
  res.render('error');
});

// 生产环境,500错误处理
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});


//输出模型
module.exports = app;

4.bin/www项目启动文件
www文件是一个node的脚本,用于分离配置和启动程序

#!/usr/bin/env node

/**
 * 依赖加载
 */

var app = require('../app');
var debug = require('debug')('extest:server');
var http = require('http');

/**
 * 定义启动端口
 */

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

/**
 * 创建HTTP服务实例
 */

var server = http.createServer(app);

/**
 * 启动网络服务监听端口
 */

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

/**
 * 前端标准化函数
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * HTTP异常事件处理函数
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * 事件绑定函数
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

5.路由
路由决定了由谁(指定脚本)去响应客户端请求,其实就是后端接口。
路由的几种写法:

var express = require('express');
var router = express.Router();

(1)router.all(path, [callback, ...] callback)
    router.all('*', [callback, ...] callback) //匹配所有的HTTP请求
    router.all('/api/*', [callback, ...] callback) //匹配所有以api开头的路由
(2)router.METHOD((path, [callback, ...] callback)
    router.get(path, [callback, ...] callback) //方法不同,其余没什么区别
    router.put(path, [callback, ...] callback)
    router.post(path, [callback, ...] callback)
(3)router.param(name, callback) //这个方法必须接受两个参数并且返回一个中间件。这个回调的第一个参数就是需要捕获的url的参数名,第二个参数可以是任一的JavaScript对象,其可能在实现返回一个中间件时被使用。这个回调方法返回的中间件决定了当URL中包含这个参数时所采取的行为。
//注意:在定义param的路由上,param回调都是第一个被调用的,它们在一个请求-响应循环中都会被调用一次并且只有一次,即使多个路由都匹配。
(4)router.route(path)//返回一个单例模式的路由的实例,之后你可以在其上施加各种HTTP动作的中间件。一个路由,多次不同调用。
    router.roue(path)
          .all(callback)
          .get(callback)
          .put(callback)
          .post(callback)
          .delete(callback)
(5)router.use([path], [function, ...] function) //给可选的path参数按照指定的路径挂载给定的中间件方法,未指定path参数,默认值为/。中间们是按序被调用的,所以顺序决定了中间件的优先级。
    router.use(callback1)//按顺序从上往下执行
    router.use(callback2)
    router.use(callback3)
module.exports = router;

6、request 和 response 对象
Request 对象 - request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性。常见属性有:

req.app:当callback为外部文件时,用req.app访问express的实例
req.baseUrl:获取路由当前安装的URL路径
req.body / req.cookies:获得「请求主体」/ Cookies。解析参数的时候需要用到body_parser和cookie_parser
req.fresh / req.stale:判断请求是否还「新鲜」
req.hostname / req.ip:获取主机名和IP地址
req.originalUrl:获取原始请求URL
req.params:获取路由的parameters
req.path:获取请求路径
req.protocol:获取协议类型
req.query:获取URL的查询参数串
req.route:获取当前匹配的路由
req.subdomains:获取子域名
req.accepts():检查可接受的请求的文档类型
req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
req.get():获取指定的HTTP请求头
req.is():判断请求头Content-Type的MIME类型

Response 对象 - response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据。常见属性有:

res.app:同req.app一样
res.append():追加指定HTTP头
res.set()在res.append()后将重置之前设置的头
res.cookie(name,value [,option]):设置Cookie
opition: domain / expires / httpOnly / maxAge / path / secure / signed
res.clearCookie():清除Cookie
res.download():传送指定路径的文件
res.get():返回指定的HTTP头
res.json():传送JSON响应
res.jsonp():传送JSONP响应
res.location():只设置响应的Location HTTP头,不设置状态码或者close response
res.redirect():设置响应的Location HTTP头,并且设置状态码302
res.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
res.send():传送HTTP响应
res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
res.set():设置HTTP头,传入object可以一次设置多个头
res.status():设置HTTP状态码
res.type():设置Content-Type的MIME类型

猜你喜欢

转载自blog.csdn.net/weixin_40970987/article/details/82592210