Express系列文章:
(一)Express核心之中間件css
在Express核心之中間件這篇文章中,咱們講解了Express的核心——中間件,理解了Express的核心功能以後,再去熟悉Express的基礎API就變得很容易了。經過進一步掌握Express的基礎知識,咱們就可使用Express進行簡單的後臺開發了。Express的核心API主要包括五類:express.xxx、app.xxx、router.xxx、request.xxx和response.xxx。html
經過掌握這五類核心API,咱們就掌握了Express的基礎了。本文的主要內容就是介紹這些基礎API。node
express是express模塊暴露出來的頂級的函數,用於生成一個應用。所以,咱們先了解一下express的應用。web
建立一個應用:express
const express = require('express');
const app = express(); 複製代碼
這裏的app就是express生成的一個主應用。一般來講一個項目只有一個應用,可是express能夠生成多個應用,其中一個是主應用,其餘的是子應用,子應用經過掛載點掛載到主應用上,子應用具備跟主應用相同的功能,這樣方便進行模塊化開發。示例:json
const express = require('express');
// 建立兩個應用 const app = express(); const admin = express(); // 經過掛載點/admin 將admin做爲子應用掛載到app主應用身上。 app.use('/admin',admin); // 子應用具備跟主應用app相同的功能 admin.get('/',(req,res,next) => { res.send('admin子應用'); }) app.listen(5000,() => { console.log('app運行在5000端口') }) 複製代碼
在上面的代碼片斷中,咱們經過express函數生成了兩個應用app和admin,而後將admin經過掛載點/admin掛載到app上。這樣之後訪問/admin都會由admin子應用控制。所以,咱們就能夠將admin抽離出來做爲一個模塊,實現模塊化開發。服務器
在Express核心之中間件這篇文章中,咱們提到中間件的分類包括內置的中間件,而內置的中間件主要就是指express自帶的中間件express.xxx
。接下來咱們將介紹幾種可能用到的中間件。網絡
const app = express();
app.post('/user',(req,res,next) => { console.log(req.body); // undefined req.on('data',(chunk) => { console.log(chunk); }) res.send('express.json') }) 複製代碼
當咱們使用post進行請求時,若是請求主體中的數據是json格式,那麼咱們經過req.body沒法獲取到請求的數據。由於在node中默認是以流來傳輸數據的,若是咱們想要獲取到body中的數據,須要監聽data。示例以下:app
const app = express();
app.post('/user',(req,res,next) => { console.log(req.body); // undefined req.on('data',(chunk) => { console.log(chunk); // {name:'hello'} }) res.send('express.json') }) 複製代碼
在上面的代碼片斷中,咱們經過req.on('data',() => {})獲取到了body中的數據。可是這種獲取數據太過麻煩了,所以express提供了內置的一些方法用於數據的獲取,express.json就是用於獲取json格式的數據。咱們只須要在獲取數據以前使用這個中間件便可。編輯器
const app = express();
app.use(express.json()); app.post('/user',(req,res,next) => { console.log(req.body); // {name:'hello'} res.send('express.json') }) 複製代碼
使用express.json中間件,咱們就能夠很方便地在req.body中獲取請求的json格式的數據。同理express還提供了幾個中間件用於處理其餘格式的數據:
經過網絡發送靜態文件,好比圖片,css文件,以及HTML文件等對web應用來講是一個很是常見的場景。咱們能夠經過res.sendFile去發送文件,可是實際上一個簡單的發送文件,處理起來很是麻煩,須要很是多的代碼量來處理各類狀況。好比,咱們發送一個簡單的css文件。
app.get("/index.css", (req, res, next) => {
res.setHeader("content-type", "text/css"); res.send("body{background:red}"); }); 複製代碼
咱們須要設置發送的文件類型或者還須要對請求頭等進行處理,試想一下,整個web網站須要請求多少css文件,多少圖片資源,若是每一個靜態資源都經過路由去處理,這樣項目會變得很是沉重。事實上,這些都是靜態資源,不會動態修改,咱們能夠將其存儲在服務器的一個目錄下,而後再從這個目錄中進行獲取便可。express.static中間件就是用來處理這種靜態文件的獲取。
const publicPath = path.resolve(__dirname,'public');
app.use(express.static(publicPath)); 複製代碼
這樣的話,咱們就能夠訪問public目下下的全部文件了。
http://localhost:5000/index.css
http://localhost:5000/1.jpg 複製代碼
注意:express會自動到public目錄下查找,所以請求文件的url不要攜帶public目錄名。
express.Router用於建立一個新的router對象,這個a路由對象能夠像一個子應用同樣設置路由,其目的一樣是用於模塊化開發。
const router = express.Router();
// rotuer相似於子應用,具備與app一樣的功能 router.get('/',(req,res) => { res.send('blog'); }) 複製代碼
app應用是express函數執行後獲得的對象,他的核心就是app.use()用於執行中間件,這咱們已經在以前的Express核心之中間件這篇文章中講述過了,並且咱們知道app.xxx等其餘方法實際上都是app.use()的語法糖,也就是說 app.xxx全部的功能均可以經過app.use來實現。所以,這裏咱們只是列舉一下一些經常使用的app方法。
主要包括如下幾種路由相關的方法:
app.all()是匹配全部的路由,不區分請求方法。示例:
app.all("/user", (req, res, next) => {
console.log("hello"); next(); }); 複製代碼
app.all('/user')既能夠匹配app.get('/user'),又能夠匹配app.post('/user')的請求,只要是/user的請求,不管是什麼方法均可以作出響應。
app.Method()支持全部的方法
這些是常見的路由請求方法
app.get("/user", (req, res, next) => {
console.log('get方法'); next(); }); app.post("/user", (req, res, next) => { console.log('post方法'); res.send("app.get"); }); 複製代碼
express默認使用jade模板,可是同時支持其餘的模板,所以若是咱們想要使用其餘的模板,須要設置模板引擎。 好比咱們想要使用ejs模板,那麼應該使用以下設置:
app.set('view engine', 'ejs');
複製代碼
app.set()中的'view engine',表示使用的文件模板格式,若是這裏設置爲ejs,那麼它會默認去views下查找ejs文件,也只查找ejs 文件。也就是說這樣設置後全部的views下的模板文件後綴都必須是ejs。不能是html這種。然而,有時候咱們更喜歡模板文件是html,可是又 但願使用ejs,這時候就可使用app.engine()進行設置。
const ejs = require('ejs');
// 設置視圖模板格式 app.set('view engine', 'html'); // 設置html引擎 將ejs模板映射到html app.engine("html", ejs.__express); // 使用ejs渲染html模板 複製代碼
app.engine()用於將EJS模板映射至".html"文件。
app.set用於設置局部變量,可是最最經常使用的是app.set('view engin')用於設置模板引擎。app.get()用於獲取app.set()設置的變量。
// 設置視圖引擎
app.set('view engine', 'html'); // 設置html引擎 將ejs模板映射到html app.engine("html", ejs.__express); // 設置局部變量 app.set('name','express'); app.get("/user", (req, res, next) => { // app.get()用於獲取 const name = app.get('name'); console.log(name); res.render('index') }); 複製代碼
app.locals一樣是用於設置局部變量,只不過經過app.locals設置的局部變量在任何地方均可以被訪問到。
// 設置
app.locals.title = 'Hello,Express' app.locals.email = 'me@myapp.com' // 獲取 cosnole.log(app.locals.title); 複製代碼
router能夠看作是app的一個子應用,app對象所具備的功能基本上router對象也均可以使用。包括router.all相似於app.all()、router.get/post/put相似於app.get/post/put、rotuer.use()相似於app.use()。router對象只是爲了更加方便路由的模塊化管理。因此app怎麼使用的,router就怎麼使用便可。
const express = require('express');
cosnt router = express.Router(); router.get('/', function (req, res) { res.send('hello world') }) 複製代碼
request是咱們請求中的request對象上具備的方法,經過這些方法能夠獲取請求的一些參數。 response是咱們請求的response對象上具備的方法,經過這些方法能夠獲取響應的一些參數。 resquest和response的參數和方法大都跟http相關,這裏只挑選幾個容易錯誤使用的進行介紹, 其餘的你們能夠查閱相關文檔。
req.baseUrl是指路由的掛載點
app.use(express.static(publicPath));
const user = express.Router(); app.use('/user',user); // 路由掛載點是/user user.get('/add',(req,res) => { console.log(req.baseUrl); // req.baseUrl就是 /user res.send('hello'); }) 複製代碼
用於獲取完整的url路徑地址。
user.get('/add',(req,res) => {
console.log(req.baseUrl); // /user console.log(req.originalUrl); // /user/add res.send('hello'); }) 複製代碼
用於進行分片下載
var range = req.range(1000)
// the type of the range if (range.type === 'bytes') { // the ranges range.forEach(function (r) { // do something with r.start and r.end }) } 複製代碼
上面的req.range(1000),表示1000個字節進行切片,而後一片一片地進行傳輸。
這篇文章主要介紹Express的一些基礎,主要包括:
掌握了這些基礎的API,再加上咱們以前學習過的Express的核心——中間件,咱們就可使用Express進行後臺開發了,就下來就進入咱們的Express進行實戰了。離全棧之路又走進了一步。