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 server
app.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/person
console.log(req.baseUrl); // /user/person
console.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`);
})