雜項 ----Express
阿新 • • 發佈:2020-08-16
一、Express的認識 1.Express框架是什麼 Express是一個基於Node平臺的web應用開發框架,它提供了一系列的強大特性,幫助你建立各種Web應用。我們可以使用 npm install express 命令進行下載。 2.Express框架特性 1.提供了方便簡潔的路由定義方式 2.對獲取HTTP請求引數進行了簡化處理 3.對模板引擎支援程度高,方便渲染動態HTML頁面 4.提供了中介軟體機制有效控制HTTP請求 5.擁有大量第三方中介軟體對功能進行擴充套件 3.原生Node.js與Express框架對比之路由 1.原生Node.js app.on('request', (req, res) => { // 獲取客戶端的請求路徑 let { pathname } = url.parse(req.url); // 對請求路徑進行判斷 不同的路徑地址響應不同的內容 if (pathname == '/' || pathname == 'index') { res.end('歡迎來到首頁'); } else if (pathname == '/list') { res.end('歡迎來到列表頁頁'); } else if (pathname == '/about') { res.end('歡迎來到關於我們頁面') } else { res.end('抱歉, 您訪問的頁面出遊了'); } }); 2.Express框架 // 當客戶端以get方式訪問/時 app.get('/', (req, res) => { -----------// 對客戶端做出響應----------------------------------------------------- // 1. send方法內部會檢測響應內容的型別 // 2. send方法會自動設定http狀態碼 // 3. send方法會幫我們自動設定響應的內容型別及編碼 res.send('Hello Express'); }); // 當客戶端以post方式訪問/add路由時 app.post('/add', (req, res) => { res.send('使用post方式請求了/add路由'); }); 4.原生Node.js與Express框架對比之獲取請求引數 1. 原生Node.js app.on('request', (req, res) => { // 獲取GET引數 let {query} = url.parse(req.url, true); // 獲取POST引數 let postData = ''; req.on('data', (chunk) => { postData += chunk; }); req.on('end', () => { console.log(querystring.parse(postData) })); }); 2.Express框架 app.get('/', (req, res) => { // 獲取GET引數 console.log(req.query); }); app.post('/', (req, res) => { // 獲取POST引數 console.log(req.body); }) 5.使用方法: // 引入Express框架 const express = require('express'); // 使用框架建立web伺服器 const app = express(); // 當客戶端以get方式訪問/路由時 app.get('/', (req, res) => { // 對客戶端做出響應 send方法會根據內容的型別自動設定請求頭---即text/html 等資料 res.send('Hello Express'); // <h2>Hello Express</h2> {say: 'hello'} }); // 程式監聽3000埠 app.listen(3000); 二、中介軟體 1.中介軟體的認識 什麼是中介軟體? 中介軟體主要由兩部分構成,中介軟體方法以及請求處理函式。 中介軟體方法由Express提供,負責攔截請求,請求處理函式由開發人員提供,負責處理請求。 #前面的app.get就是中介軟體方法由系統提供,後面就是處理函式,由開發人員提供 app.get('請求路徑', '處理函式') // 接收並處理get請求 app.post('請求路徑', '處理函式') // 接收並處理post請求 2.中介軟體的使用(next) 可以針對同一個請求設定多箇中間件,對同一個請求進行多次處理。 預設情況下,請求從上到下依次匹配中介軟體,一旦匹配成功,終止匹配。 可以呼叫next方法將請求的控制權交給下一個中介軟體,直到遇到結束請求的中介軟體。 app.get('/request', (req, res, next) => { req.name = "張三"; next(); }); app.get('/request', (req, res) => { res.send(req.name); }); 3.app.use中介軟體用法 1.app.use 匹配所有的請求方式,可以直接傳入請求處理函式,代表接收所有的請求。 app.use((req, res, next) => { console.log(req.url); next(); }); 2.app.use 第一個引數也可以傳入請求地址,代表不論什麼請求方式,只要是這個請求地址就接收這個請求。 app.use('/admin', (req, res, next) => { console.log(req.url); next(); }); 3.友情提示: next是繼續匹配下一個相同的url,比如請求list,他會和第一個use匹配,然後next跳過另一個use和app.get匹配 app.use((req,res,next)=>{ console.log('app.use') next() }) app.use('/request',(req,res)=>{ res.send('request') }) app.get('/list',(req,res,next)=>{ res.send('list1') }) 4.中介軟體應用 1.路由保護,客戶端在訪問需要登入的頁面時,可以先使用中介軟體判斷使用者登入狀態,使用者如果未登入,則攔截請求,直接響應,禁止使用者進入需要登入的頁面。 2.網站維護公告,在所有路由的最上面定義接收所有請求的中介軟體,直接為客戶端做出響應,網站正在維護中。(放在最前面,接收所有請求並返回維護頁面) 3.自定義404頁面(放在最後面,因為next會一個一個匹配,如果沒匹配到就是not found) --res.status(404).send('當前訪問的頁面是不存在的') 5.錯誤處理中介軟體(err) 在程式執行的過程中,不可避免的會出現一些無法預料的錯誤,比如檔案讀取失敗,資料庫連線失敗。 錯誤處理中介軟體是一個集中處理錯誤的地方。 app.use((err, req, res, next) => { res.status(500).send('伺服器發生未知錯誤'); }) 錯誤處理中介軟體只能處理同步函式,非同步函式不行,非同步函式的錯誤需要主動通過next觸發 當程式出現錯誤時,呼叫next()方法,並且將錯誤資訊通過引數的形式傳遞給next()方法,即可觸發錯誤處理中介軟體。 app.get("/", (req, res, next) => { fs.readFile("/file-does-not-exist", (err, data) => { if (err) { next(err); } }); }); 6.捕獲錯誤 tyr{} catch(){} 在node.js中,非同步API的錯誤資訊都是通過回撥函式獲取的,支援Promise物件的非同步API發生錯誤可以通過catch方法捕獲。 try catch 只能捕獲同步或非同步函式的,不能捕獲回撥函式或Promise物件的 try catch 可以捕獲非同步函式以及其他同步程式碼在執行過程中發生的錯誤,但是不能其他型別的API發生的錯誤。 app.get("/", async (req, res, next) => { try { await User.find({name: '張三'}) }catch(ex) { next(ex); } }); 三、Express的進階使用(路由) 1.構建模組化路由(可以分級) const express = require('express') // 建立路由物件 const home = express.Router(); // 將路由和請求路徑進行匹配---------->一級 app.use('/home', home); // 在home路由下繼續建立路由---------->二級 home.get('/index', () => { // /home/index res.send('歡迎來到部落格展示頁面'); }); --------------------------------------------->訪問的為home/index 2.GET引數的獲取 Express框架中使用req.query即可獲取GET引數,框架內部會將GET引數轉換為物件並返回。 // 接收位址列中問號後面的引數 // 例如: http://localhost:3000/?name=zhangsan&age=30 app.get('/', (req, res) => { console.log(req.query); // 獲得{"name": "zhangsan", "age": "30"} }); 3.POST引數的獲取 Express中接收post請求引數需要藉助第三方包 body-parser。 // 引入body-parser模組 const bodyParser = require('body-parser'); // 配置body-parser模組 // extended: false 方法內部使用querystring模組處理請求引數的格式 // extended: true 方法內部使用第三方模組qs處理請求引數的格式 app.use(bodyParser.urlencoded({ extended: false })); // 接收請求 app.post('/add', (req, res) => { // 接收請求引數 console.log(req.body); }) 4.Express路由引數 -----------》localhost:3000/find/123 app.get('/find/:id', (req, res) => { console.log(req.params); // {id: 123} }); 5.靜態資源的處理 通過Express內建的express.static可以方便地託管靜態檔案,例如img、CSS、JavaScript 檔案等。 app.use(express.static('public')); 四、Express中的模板引擎 1.使用: 同時安裝:使用npm install art-template express-art-template命令進行安裝。 2.範例 // 當渲染字尾為art的模板時 使用express-art-template app.engine('art', require('express-art-template')); // 設定模板存放目錄 app.set('views', path.join(__dirname, 'views')); // 渲染模板時不寫字尾 預設拼接art字尾 app.set('view engine', 'art'); app.get('/', (req, res) => { // 渲染模板 res.render('index'); }); 究極範例: const express = require('express'); const path = require('path'); const app = express(); // 1.告訴express框架使用什麼模板引擎渲染什麼字尾的模板檔案 // 1.模板字尾 // 2.使用的模板疫情 app.engine('art', require('express-art-template')) // 2.告訴express框架模板存放的位置是什麼 app.set('views', path.join(__dirname, 'views')) // 3.告訴express框架模板的預設字尾是什麼 app.set('view engine', 'art'); app.get('/index', (req, res) => { // 1. 拼接模板路徑 // 2. 拼接模板字尾 // 3. 哪一個模板和哪一個資料進行拼接 // 4. 將拼接結果響應給了客戶端 res.render('index', { msg: 'message' }) }); app.get('/list', (req, res) => { res.render('list', { msg: 'list page' }) }) // 埠監聽 app.listen(3000); ----------------------------------PS-------------------------------------- 1.要注意模板中的外鏈檔案,修改他們的預設路徑,因為那些靜態資源是瀏覽器解析的 他的相對路徑是,相對於你在瀏覽器中開啟的網頁的地址 如admin/login,瀏覽器把localhost/admin看成是路徑,Login看成檔案,所以相對路徑是admin 他會把相對路徑admin和外鏈路徑css/base.css拼在一起形成admin/css/base.css,然後去靜態資原始檔夾如:public裡獲取 所以我們可以在外鏈路徑新增完整的路徑 2.app.locals 物件 將變數設定到app.locals物件下面,這個資料在所有的模板中都可以獲取到。 app.locals.users = [{ name: '張三', age: 20 },{ name: '李四', age: 20 }]