1.express()
- 基于Node.js平臺,快速、開放、極簡的web開發框架。
創建一個Express
應用.express()
是一個由express
模塊導出的入口top-level
函數.
const express = require('express');
let app = express();
1.1 靜態資源管理
express.static(root, [options])
-
express.static
,是Express
內置的唯一一個中間件.是基于serve-static
開發的,負責托管Express
應用內的靜態資源. -
root
,參數指的是靜態資源文件所在的根目錄. -
options
,對象是可選的,支持以下屬性-
dotfiles
,String
類型,服務dotfiles
的選項.可能的值是allow
,deny
,ignore
,默認值為ignore
-
maxAge
,以毫秒為單位設置Cache-Control
標題頭的最大屬性或ms
格式的字符串,默認為0
-
etag
,Boolean
類型,啟用或禁用etag
生成 -
extensions
,Mixed
,設置文件擴展 -
index
,Boolean
類型,發送目錄索引,設置false
為禁用 -
redirect
,Boolean
類型,當路徑是一個目錄時,重定向到尾隨/
, -
etHeaders
,Function
類型,設置HTTP
標頭以供文件使用的函數
-
1.2. Etag
ETag
是HTTP1.1
中才加入的一個屬性,用來幫助服務器控制Web
端的緩存驗證.它的原理是這樣的,當瀏覽器請求服務器的某項資源A
時, 服務器根據A
算出一個哈希值(3f80f-1b6-3e1cb03b)
并通過ETag
返回給瀏覽器,瀏覽器把3f80f-1b6-3e1cb03b
和A
同時緩存在本地,當下次再次向服務器請求A時,會通過類似If-None-Match: "3f80f-1b6-3e1cb03b"
的請求頭把ETag
發送給服務器,服務器再次計算A
的哈希值并和瀏覽器返回的值做比較,如果發現A
發生了變化就把A返回給瀏覽器200
,如果發現A
沒有變化就給瀏覽器返回一個304
未修改.這樣通過控制瀏覽器端的緩存,可以節省服務器的帶寬,因為服務器不需要每次都把全量數據返回給客戶端.注:
HTTP
中并沒有指定如何生成ETag
,哈希是比較理想的選擇.
1.3. 建立基本的HTTP服務器
const express = require('express');
let app = express();app.get('/', (req, res) => {res.send('hello world');
});app.listen(3000);
1.4. app
對象的locals
屬性
- 可以在
locals
對象上自定義屬性 app.locals.title = 'my express title';
app.locals.email = 'express@express.com';
{ settings: { 'x-powered-by': true,etag: 'weak','etag fn': [Function: wetag],env: 'development','query parser': 'extended','query parser fn': [Function: parseExtendedQueryString],'subdomain offset': 2,'trust proxy': false,'trust proxy fn': [Function: trustNone],view: [Function: View],views: 'E:\\Self\\point\\views','jsonp callback name': 'callback' },title: 'my express title',email: 'express@express.com'
}
1.5. app.all(path, callback(req, res, next){...})
app.all('*', fn1, fn2...)
// 等價于
app.all('*', fn1)
app.all('*', fn2)
1.6. 刪除請求路由
app.delete(path, callback [, callback ...])
- 將HTTP刪除請求路由到具有指定回調函數的指定路徑
app.delete('/', function (req, res) {res.send('DELETE request to homepage');
});
1.7. 禁用啟用某個屬性
- 禁用
app.disable(name)
,app.disabled(name)
- 啟用
app.able(name)
,app.abled(name)
app.set('username', 'express server');
console.log(app.get('username')); //express serverapp.set('username', 'express server');
app.disable('username');
console.log(app.get('username')); //false
1.8. 模板引擎
app.engine(ext, callback)
- 根據不同的模板引擎的擴展名,使用不同的模板
app.engine('jade', require('jade').__express);
app.engine('html', require('ejs').renderFile);
1.9. 設置與獲取屬性
app.set('title', 'text');
console.log(app.get('title')); // text
1.10. get
請求
app.get(path, callback [, callback ...])
- 將
HTTP
獲取請求路由到具有指定回調函數的指定路徑
app.get('/', function (req, res) {res.send('GET request to homepage');
});
1.11. 監聽端口
app.listen(port, [hostname], [backlog], [callback(err)])
- 監聽端口,主機,最大連接數量,回調函數
const express = require('express');
let app = express();app.get('/', function (req, res) {res.send('home page');
});app.listen(3000, 'localhost', 100, function (err) {if (err) {console.log('error');} else {console.log('the http server is running at localhost:3333');}
});
1.12. 路由參數
app.param([name],callback(req, res, next, id){...})
將回調觸發器添加到路由參數, 其中名稱是參數的名稱或它們的數組, 函數是回調函數.回調函數的參數是請求對象、響應對象、下一個中間件以及該參數的值 (按該順序).如果 name 是一個數組, 則回調觸發器按聲明的順序注冊在其中聲明的每個參數.此外, 對于每個已聲明的參數, 除了最后一個外, 回調中的下一個調用將調用下一個聲明的參數的回調.對于最后一個參數, 調用 next 將調用當前正在處理的路由的下一個中間件, 就像如果名稱只是一個字符串一樣.
- 參數是一個字符串
app.param('id', (req, res, next, id) => {console.log('called only once');next();
});app.get('/user/:id', (req, res, next) => {console.log('although this matches');next();
});app.get('/user/:id', (req, res) => {console.log('this matches too');res.send('end user id');
});
/**
called only once
although this matches
this matches too
*/
- 參數是一個數組
app.param(['id', 'page'], (req, res, next, id) => {console.log('called only once', id);next();
});app.get('/user/:id/:page', (req, res, next) => {console.log('although this matches');next();
});app.get('/user/:id/:page', (req, res) => {console.log('this matches too');res.send('end user id');
});
/**
called only once kkk
called only once 555
although this matches
this matches too
*/
1.13. app.path()
- 返回應用程序的規范化路徑
let express = require('express');
let app = express();
let blog = express();
let blogAdmin = express();app.use('/blog', blog);
blog.use('/admin', blogAdmin);console.log(app.path());
console.log(blog.path());
console.log(blogAdmin.path());
1.14. 模板渲染
app.render(view, [locals], callback(err,html){...})
- 回調函數返回視圖的呈現 HTML
1.15. 路由設置
app.route(path)
- 返回單個路由的實例
app.route('/one').all(function (req, res, next) {console.log('route all');next();}).get(function (req, res, next) {res.json({code: 2589,msg: 'route get msg'});}).post(function (req, res, next) {res.send('this is route post send msg');});
1.16. 中間件
app.use([path,] callback(req, res, next){...})
- 在路徑上裝載中間件函數.如果未指定路徑, 則默認為
/
- 路徑可以是表示路徑、路徑模式、匹配路徑的正則表達式或其組合數組的字符串
-
app.use()
中間件可以使用正則匹配路徑,可以有多個中間件函數 - 可使用的地方
app.use(express.static(__dirname + '/public'));
app.use('/static', express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/public'));
app.use(logger());
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/files'));
app.use(express.static(__dirname + '/uploads'));
- 中間件示例
app.use('/user/person', (req, res, next) => {console.log(req.originalUrl); // /user/personconsole.log(req.baseUrl); // /user/personconsole.log(req.path); // /next();
});
- 如果使用了
app.use(callback())
,就不會觸發app.get('/', callback())
// this middleware will not allow the request to go beyond it
app.use((req, res, next) => {res.send('Hello World');
})// requests will never reach this route
app.get('/', (req, res) => {res.send('Welcome');
})