Express快速入門

1、概述

Fast, unopinionated, minimalist web framework for Node.jsjavascript

Express是一個基於Node.js平臺的Web應用開發框架。它提供了各類模塊,能夠快速地建立各類Web和移動應用。html

官網地址java

2、原理

一、http模塊

Express框架在node.js的http模塊之上,對http模塊進行了封裝,相對於加了一箇中間層。node

使用Node.js的http模塊建立服務器:web

var http = require("http");
var app = http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end("Hello world!");
});
app.listen(3000, "localhost");

使用Express框架實現:express

var express = require('express');
var app = express();
app.get('/', function (req, res) {
  res.send('Hello world!');
});
app.listen(3000);

二、中間件

中間件就是處理HTTP請求的函數,用來完成各類特定的任務。其最大特色就是,當一箇中間件處理完成以後,再傳遞給下一個中間件。npm

模塊http的createServer方法,生成一個服務器實例,容許在運行過程當中,調用一系列中間件。當一個HTTP請求進入服務器,服務器實例會調用第一個中間件,完成以後根據設置,決定是否再調用下一個中間件。每一箇中間件包含請求對象和響應對象,根據須要,決定是否調用next回調函數,將對象傳遞給下一個中間件。若是回調函數next帶有參數,則表示拋出錯誤,參數爲錯誤信息。拋出錯誤以後,後面的中間件將再也不執行,直到發現一個錯誤處理函數爲止。json

三、use方法

use是express調用中間件的方法,它返回一個函數。服務器

app.use(function(request, response, next) {});

除了在回調函數內部判斷請求的地址,也容許將請求的地址寫在use方法的第一個參數。cookie

app.use('/', function(request, response, next) {});

針對不一樣的請求,express還提供了use方法的一些別名,包括all和http動詞。

app.all('*', function(request, response, next) {});
app.get('/', function(request, response, next) {});

四、路由

所謂路由,就是爲不一樣的訪問路徑,指定不一樣的處理方法。

  • express的Router類,能夠建立模塊化的路由的處理程序
  • router實例對象的route方法,能夠接受訪問路徑做爲參數
  • use方法爲router對象指定中間件,即在數據發送給用戶以前,對數據進行處理
  • router對象的param方法用於路徑參數的處理
  • 調用app的route方法,建立路由。該方法會返回一個Route實例,它能夠繼續使用全部的HTTP方法

五、模板引擎

express支持多種模板引擎,如Handlebars等。模板默認存放在views目錄,以html爲後綴名。

安裝模板引擎:

npm install hbs --save-dev

加載hbs模塊:

require('hbs');

指定模板文件的後綴名:

app.set('view engine', 'html');

運行hbs模塊:

app.engine('html', hbs.__express);

渲染模板:

res.render('index');

以上代碼把views目錄下的index.html文件,交給hbs模板引擎進行渲染。

3、建立工程

安裝:

npm install -g express-generator@4

建立:

express -e <projectname>

下載:

cd <projectname> && npm install

啓動:

npm start

4、工程配置

一、目錄結構

  • bin,存放啓動項目的腳本文件
  • node_modules,存放全部依賴庫
  • public,存放靜態文件
  • routes,存放路由文件
  • views,存放頁面文件
  • package.json,項目依賴配置文件
  • app.js,應用核心配置文件

二、配置文件app.js

// 加載依賴庫
var express = require('express'); 
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

// 加載路由控制
var routes = require('./routes/index');

// 建立項目實例
var app = express();

// 定義EJS模板引擎和模板文件位置
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// 定義icon圖標
app.use(favicon(__dirname + '/public/favicon.ico'));
// 定義日誌和輸出級別
app.use(logger('dev'));
// 定義數據解析器
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// 定義cookie解析器
app.use(cookieParser());
// 定義靜態文件目錄
app.use(express.static(path.join(__dirname, 'public')));

// 匹配路徑和路由
app.use('/', routes);

// 404錯誤處理
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// 開發環境,500錯誤處理和錯誤堆棧跟蹤
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
    });
  });
}

// 生產環境,500錯誤處理
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

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

三、啓動文件./bin/www

#!/usr/bin/env node

// 依賴加載
var app = require('../app');
var debug = require('debug')('nodejs-demo: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)) {
    return val;
  }
  if (port >= 0) {
    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);
}

參考文章:

阮一峯:JavaScript 標準參考教程(alpha)

張丹:Node.js開發框架Express4.x

相關文章
相關標籤/搜索