express.Router
Express.js 4.0 有加入一個新的 Router 功能,它就像一個迷你的应用程序,可以让内部的路由改写更为方便,更具备弹性。
首先来看下express3.0版本的旧版路由定义的写法:
// ---- 基本設定 ----
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
// ---- ROUTES ----
// 舊方法
app.get('/sample', function(req, res) {
res.send('this is a sample!');
});
// ---- 啟動伺服器 ----
app.listen(port);
然后你去浏览器输入
http://localhost:8080/sample/ 就能看见 > this is a sample!
再来看看 Express Router
下面我们加入 4.0 的 Router 设置更多的更灵活的路由页面。
// ---- 基本設定 ----
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
// ---- ROUTES ----
// 舊方法
app.get('/sample', function(req, res) {
res.send('this is a sample!');
});
// Express Router
// 建立 Router 物件
var router = express.Router();
// 首頁路由 (http://localhost:8080)
router.get('/', function(req, res) {
res.send('home page!');
});
// 另一張網頁路由 (http://localhost:8080/about)
router.get('/about', function(req, res) {
res.send('about page!');
});
// 將路由套用至應用程式
app.use('/', router);
// ---- 啟動伺服器 ----
app.listen(port);
这里我们建立了一个 Router 物件,然后设定这个物件的路由规则,最后再将这个 Router 物件的路由规则嵌套到应用程序中:
app.use('/', router);
如果是跨页面不同文件中的话就应该使用 module.exports 和 require 来引入 Router 对象:
const index = require('./routes/index');
const users = require('./routes/users');
const login = require('./routes/login');
const register = require('./routes/register');
const app = express();
app.use('/', index);
app.use('/users', users);
app.use('/login', login);
app.use('/register', register);
所有我们这样就建立了两个新的路由页面: 1. http://localhost:8080 2. http://localhost:8080/about
路由套用到应用程序中时,我们可以指定路由的基础路径如下:
app.use('/app', router);
// 这里基础路径指定为 => /app
于是又有两个新路由页面了: 1. http://localhost:8080/app 2. http://localhost:8080/app/about
通过 Router 我们就可以很方便的将不同功能的路由区分开来,将路由业务细分化更具有模块化更加灵活了。
Route Middleware
Express 的 middleware 功能可以让请求(request)在被处理之前,先执行一些前置作业,例如检查使用者是否有登入或是记录了一些使用者的浏览资料等等,凡是需要在实际处理请求之前要做的动作,都可以使用 middleware 來处理。
// ... (略)
// 建立 Router 物件
var router = express.Router();
// 在每一個請求被處理之前都會執行的 middleware
router.use(function(req, res, next) {
// 輸出記錄訊息至終端機
console.log(req.method, req.url);
// 繼續路由處理
next();
});
// 首頁路由 (http://localhost:8080)
router.get('/', function(req, res) {
res.send('home page!');
});
// 另一張網頁路由 (http://localhost:8080/about)
router.get('/about', function(req, res) {
res.send('about page!');
});
// 將路由套用至應用程式
app.use('/', router);
// ... (略)
这样一來,只要有任何请求要处理的时候,终端上面都会输出对应的记录信息。
注意: 在使用 middleware 時必須要注意他的放置位置必須要在 routes 之前,程式在執行的時候會依據 middleware 與 routes 的先後順序來執行,如果不小心將 middleware 放在 routes 之後,那麼在 routes 處理完請求之後就會結束處理的流程,這樣 middleware 就根本不會執行。
参数路由(Route with Parameters)
路由的規則除了使用固定的字串之外,也可以包含會變動參數,下面這個例子可以將使用者的名稱透過 URL 傳入程式中,並且根據使用者的名稱輸出訊息:
// ... (略)
// 含有參數的路由 (http://localhost:8080/hello/:name)
router.get('/hello/:name', function(req, res) {
res.send('hello ' + req.params.name + '!');
});
// 將路由套用至應用程式
app.use('/', router);
// ... (略)
這裡的 :name 就像一個變數名稱,如果我們輸入的 URL 為 http://localhost:8080/hello/seal,那麼在程式中的 req.params.name 所抓取到的值就會是 ‘seal’,透過這樣的機制我們就可以跟不同的使用者打招呼。
验证参数
有時候我們會需要針對傳入的路由參數來進行篩選或驗證,例如檢查使用者所輸入的字串是否是合法的名稱,這時候就可以使用 .param() 這個專門用來處理參數的 middleware:
// ... (略)
// 驗證 :name 的 route middleware
router.param('name', function(req, res, next, name) {
// 在這裡驗證資料
// ... ... ...
// 顯示驗證訊息
console.log('doing name validations on ' + name);
// 當驗證成功時,將其儲存至 req
req.name = name;
// 繼續後續的處理流程
next();
});
// 含有參數的路由 (http://localhost:8080/hello/:name)
router.get('/hello/:name', function(req, res) {
res.send('hello ' + req.name + '!');
});
// 將路由套用至應用程式
app.use('/', router);
// ... (略)
這樣在每次有 :name 參數傳入時,就會先執行這裡新增的 middleware,經過驗證確定沒問題之後,再將傳入的名稱儲存至 req 中,透過這樣的方式將驗證過的資料傳遞給 .get 路由,所以在 .get 路由中,我們也將原本的 req.params.name 改為 req.name。
現在當我們開啟 http://localhost:8080/hello/seal 的時候,終端機中就會出現驗證的訊息:
登录路由
除了使用 express.Router() 的方式來建立路由之外,我們也可以使用 app.route 直接在應用程式上新增路由,這種方式是 Router 的簡略寫法,語法看起來就跟傳統上的 app.get 很類似。
使用 app.route 有個好處是可以讓我們一次針對一個路由新增好幾個動作,例如我們想要使用 GET 顯示登入表單,並且使用 POST 處理表單:
// ... (略)
// ---- ROUTES ----
app.route('/login')
// 顯示登入表單 (GET http://localhost:8080/login)
.get(function(req, res) {
res.send('this is the login form');
})
// 處理登入表單 (POST http://localhost:8080/login)
.post(function(req, res) {
console.log('processing');
res.send('processing the login form!');
});
// ... (略)
這樣一來程式就可以在 /login 這個路由上將 GET 與 POST 分開處理,而且這樣的寫法既方便又簡潔。