Node.js學習之路24——Express框架的app物件

Karuru發表於2019-02-16

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

ETagHTTP1.1中才加入的一個屬性,用來幫助伺服器控制Web端的快取驗證.它的原理是這樣的,當瀏覽器請求伺服器的某項資源A時, 伺服器根據A算出一個雜湊值(3f80f-1b6-3e1cb03b)並通過ETag返回給瀏覽器,瀏覽器把3f80f-1b6-3e1cb03bA同時快取在本地,當下次再次向伺服器請求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`);
})

相關文章