Node中間層實踐(五)——express-中間層的邏輯處理

版權聲明:此文首發於個人我的站Keyon Y,轉載請註明出處。前端

項目地址:github.com/KeyonY/Node…node

express的邏輯處理分爲兩部分:轉發後端接口中間件webpack

轉發後端接口

後端提供的接口分爲兩類:ios

  • 渲染頁面使用的數據接口
  • 前端部分發送ajax請求的請求接口

數據接口

就是url的連接所能訪問的頁面。git

先使用router.get()註冊路由,路由內先經過axios訪問後端獲取頁面數據response,經過 res.render()返回一個自定義的對象,將response做爲對象的屬性傳遞到pug模板頁面中,在pug頁面中即可以隨意使用response。github

參考github項目中 config/routes/default.js文件:web

// 首頁
router.get('/', addUser, (req, res, next) => {
	axios.all([
		axios.get('/Api/Carous'),
		axios.get('/Api/Cars/Top10', {params: {page: req.query.page || 1}}),
	])
		.then(axios.spread(function (res1, res2){
			config.throwError(next, res1, res2);
			var page = req.query.page || 1;
			res.render('Default/index', {
				title: config.title('首頁'),
				keywords: config.keywords,
				description: config.description,
				menuNav: 0,
				carList: res1.data.Data,
				top10: res2.data.Data.slice((page-1)*3,page*3)
			});
		})).catch(e => {
		config.renderError(req, res, e);
	})
});
複製代碼

請求接口

是前端發送ajax請求的接口。ajax

與數據接口的區別就是,中間層只作兩件事:express

  • 使用axios,轉發前端的請求給後端
  • 使用res.send(),轉發後端的響應給前端
// get請求
router.get('/User/Role', (req, res, next) => {
    axios.get(config.origin + '/Api/User/Role', config.axiosHeaders(req, {
        params: {role: req.query.role}
    }))
        .then(res1 => {
            res.send(res1.data);
        }).catch(e => {
            config.sendError(res, e);
    })
})

// post請求
router.post('/User/SendRequest', (req, res, next) => {
	axios.post(config.origin + '/Api/User/SendRequest', {
		userID: req.body.userID || null,
		requestID: JSON.parse(req.body.requestID) || null
	}, config.axiosHeaders(req))
		.then((res2) => {
			res.send(res2.data);
		}).catch((e) => {
		config.sendError(res, e);
	})
});
複製代碼

post請求沒法直接讀取請求體,須要安裝body-parser依賴npm

npm i –save body-parser

並在app.js掛載這個依賴

app.use(bodyParser.urlencoded({extended: false}));
複製代碼

獲取前端請求中的參數

分爲三種狀況:

  • 獲取帶有參數的路由中的參數
router.get('/Cars/:id', (req, res, next) => {
    axios.get(config.origin + '/Api/Cars', {
        params: {role: req.params.id}  // req.params.id獲取url中的參數
    }))
    ...
})
複製代碼
  • 獲取get請求的參數
// 例如這樣的請求 /Cars/Search?q=tobi
router.get('/Cars/Search', (req, res, next) => {
    axios.get(config.origin + '/Api/Cars/Search', {
        params: {car: req.query.q}  // req.query.q獲取參數
    }))
    ...
})
複製代碼
  • 獲取post請求的參數
router.post('/Cars/Search', (req, res, next) => {
    axios.post(config.origin + '/Api/Cars/Search', {
        car: req.body.name  // req.body.name獲取請求體中的參數
    }))
    ...
})
複製代碼

post請求轉發數組對象

express post請求,獲取客戶端請求中的數組時,如果直接post一個數組,則express沒法獲取數組,須要在客戶端對數組進行序列化,在中間層反序列化:

// 客戶端
$.ajax({
	url: '/Api/Mas/SendInfo',
	type: 'POST',
	data: {userID: userId, requestID: JSON.stringify(selected)},  // 序列化
	success: function (res) {
		log(res);
		if(res.Status == 0){
			$thisModal.hide();
			$('#modal_cds').show();
		}
	}
})
		
// 中間層
axios.post(config.origin + '/Api/Mas/SendInfo', {
	userID: req.body.userID || null,
	requestID: JSON.parse(req.body.requestID) || null    // 反序列化
}, config.axiosHeaders(req))
複製代碼

中間層不要傳遞有可能不存在的屬性

千萬不要在中間層傳遞有可能不存在的property!

千萬不要在中間層傳遞有可能不存在的property!

千萬不要在中間層傳遞有可能不存在的property!

重要的事情說三遍,否則出現下面的bug 都不知道在哪裏找。

(node:20352) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property ‘data’ of undefined

中間件

Express 是一個自身功能極簡,徹底是由路由和中間件構成一個的 web 開發框架:從本質上來講,一個 Express 應用就是在調用各類中間件。

中間件(Middleware) 是一個函數,它能夠訪問請求對象(request object (req)), 響應對象(response object (res)), 和 web 應用中處於請求-響應循環流程中的中間件,通常被命名爲 next 的變量。

中間件的功能包括:

  • 執行任何代碼。
  • 修改請求和響應對象。
  • 終結請求-響應循環。
  • 調用堆棧中的下一個中間件。

若是當前中間件沒有終結請求-響應循環,則必須調用 next() 方法將控制權交給下一個中間件,不然請求就會掛起。

Express 應用可以使用以下幾種中間件:

  • 應用級中間件
  • 路由級中間件
  • 錯誤處理中間件
  • 內置中間件
  • 第三方中間件

使用可選擇掛載路徑,可在應用級別或路由級別裝載中間件。另外,你還能夠同時裝載一系列中間件函數,從而在一個掛載點上建立一個子中間件棧。

使用路由級中間件處理request對象

var addUser = require('../../middleware/addUser');
    ...
router.get('/Car/List', addUser, (req, res, next) => {
    ...
})
複製代碼

addUser即中間件,是一個方法,接受路由中的req,res,next三個參數,必須以**next();**結束代碼,這樣將函數指針從addUser,交給(req, res, next) => { …}。

使用中間件,能夠獲取請求頭中的cookies,以驗證用戶登陸信息

獲取cookie的內容,須要安裝cookie-parser依賴

npm i –save cookie-parser

在app.js中,掛載這個依賴就可使用了。

app.use(cookieParser());
複製代碼

錯誤處理中間件-Error Handle

注意Error Handle的掛載的順序,通常掛載到app.use()下,且放在最後。 請參考本系列博文的第二篇Node中間層實踐(二)——搭建項目框架中app.js的介紹,或查看github項目代碼的app.js。


歡迎繼續關注系列的其餘文章
Node中間層實踐(一)——基於NodeJS的全棧式開發
Node中間層實踐(二)——搭建項目框架
Node中間層實踐(三)——webpack配置
Node中間層實踐(四)——模板引擎pug
Node中間層實踐(五)——express-中間層的邏輯處理

相關文章
相關標籤/搜索