Node.js自2009年誕生以來,發展速度至關驚人,目前各類開發框架層出不窮,國內外各大公司都在使用,如國內的阿里的淘寶、天貓、阿里雲、螞蟻金服,騰訊視頻、攜程、百度、網易、蘇寧、京東、愛奇藝、去哪兒、有贊、貝殼找房等等好多企業都在使用,大部分企業把Node.js做爲中間層去應用,今天和你們簡單說說關於基於Nodejs打造Web架構中間層的一些知識。php
中間層(Middle Tier)也稱做應用程序服務器層或應用服務層,是用戶接口或 Web 客戶端與數據庫之間的邏輯層。典型狀況下 Web 服務器位於該層,業務對象在此實例化。中間層是生成並操做接收信息的業務規則和函數的集合。它們經過業務規則(能夠頻繁更改)完成該任務,並由此被封裝到在物理上與應用程序程序邏輯自己相獨立的組件中。html
以Node做爲中間層,當客戶端打開一個網站時,先請求到node服務器這一層,經過node服務器轉發請求到後端的服務器,獲取數據,而後返給node的模板引擎,根據視圖模板渲染好模板字符串頁面,再返回給客戶端,直接展現頁面,如圖:前端
Nginx是一個高性能的WEB服務器和反向代理服務器,最經常使用的軟件負載均衡器。node
當訪問量比較大時,頻繁的請求,會給服務帶來很大壓力,經過負載均衡、分流,減輕服務器的壓力;另外一方面,網站部署在多臺服務器,當某臺服務器故障的時候,能夠立刻切換到其它服務器,還能保證網站能正常訪問,這就是負載均衡的優點。jquery
中間件(MiddleWare)是一種獨立的系統軟件服務程序,分佈式應用軟件藉助這種軟件在不一樣的技術之間共享資源,中間件位於客戶機服務器的操做系統之上,管理計算資源和網絡通訊。從這個意義上能夠用一個等式來表示中間件:中間件=平臺+通訊,這也就限定了只有用於分佈式系統中才能叫中間件,同時也把它與支撐軟件和實用軟件區分開來。ios
在NodeJS中,中間件主要是指封裝全部Http請求細節處理的方法。一次Http請求一般包含不少工做,如記錄日誌、ip過濾、查詢字符串、請求體解析、Cookie處理、權限驗證、參數驗證、異常處理等,但對於Web應用而言,並不但願接觸到這麼多細節性的處理,所以引入中間件來簡化和隔離這些基礎設施與業務邏輯之間的細節,讓開發者可以關注在業務的開發上,以達到提高開發效率的目的。中間件能夠理解爲一個對用戶請求進行過濾和預處理的東西,它通常不會直接對客戶端進行相應,而是將處理以後的結果傳遞下去。簡單來講就是實現某種功能的函數。web
Express是一個自身功能極簡,徹底是路由和中間件構成一個web開發框架:從本質上來講,一個Express應用就是在調用各類中間件,中間件機制如圖所示: ajax
中間件是從Http請求發起到響應結束過程當中的處理方法,一般須要對請求和響應進行處理,所以一個基本的中間件的形式以下:redis
`const middleware = (req, res, next) => {
// TODO
next()
}`算法
Node.js是一個Javascript運行環境。Node.js 使用事件驅動, 非阻塞I/O 模型而得以輕量和高效,很是適合在分佈式設備上運行數據密集型的實時應用。Node.js是單進程、單線程運行機制,經過事件輪詢(event loop)來實現併發操做,並且性能很好。
Node.js最大的改良架構就是"增長了中間層",先後端分離,使用Node.js來作‘BBF(backend of frontend)’在傳統後端加入了Node.js這一層,經過此有兩點好處,前端接管了view層,後端渲染也開始所有由前端掌控,另外一個就是接口層增長了一層。在先後端分離的自然選擇下,Node.js中間層能夠承擔更多的責任。
前面寫了不少理論方面的知識,接下來本身手動來簡單實現Node.js基於Koa框架實現的中間層。
先了解一下後端提供的一個接口,根據前端頁面輸入不一樣帳號信息,後端接口會返回不一樣的值,如圖:
這段PHP代碼是根據前端傳給不一樣的用戶名和密碼狀態返回不一樣的狀態碼。
前端頁面用了ejs模板引擎採用服務端渲染方式來進行。前端頁面主要有三個代碼的文件,app.js,admin.js,admin.ejs。
一、是app.js代碼
`const Koa = require('koa');
// 路由
const Router = require('koa-router');
// 模板引擎
const ejs = require('koa-ejs');
// 數據解析
const body = require('koa-bodyparser');
// 處理靜態文件
const static = require("koa-static");
const path = require('path');
const app = new Koa();
ejs(app,{
root:path.resolve(__dirname,"template"), layout:false, viewExt:"ejs", cache:false, debug:false
})
const router = new Router();
app.use(body());
router.get("/",ctx => {
ctx.body = '主頁';
})
router.use("/admin",require("./router/admin"));
app.use(static('./static'));
app.use(router.routes());
app.listen(3000);`
二、登陸頁面文件,用ejs模板引擎來處理
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>我是管理頁面</title> <script src="/js/jquery.min.js"></script>
</head>
<body>
<p>用戶:<input type="text"></p> <p>密碼:<input type="password"></p> <button>提交</button> <script> $(function(){ $('button').click(function(){ var username = $(':text').val(); var password = $(':password').val(); $.ajax({ url:'/admin/login', method:'post', data:{ username, password }, success(data){ console.log(data); } }) }) }) </script>
</body>
</html>`
一、使用上面的登陸頁代碼,而後admin.js頁面代碼以下
`const Router = require('koa-router');
const querystring = require('querystring');
const router = new Router();
router.get('/',async ctx=>{
await ctx.render('admin/admin')
})
router.post("/login",async ctx => {
const { username,password } = ctx.request.body; console.log(username,password);
})
module.exports = router.routes();`
此時登陸頁面輸入用戶名和密碼點擊提交時會輸出結構以下代碼:
``^CedzdeMacBook-Pro-5:0323 edz$ nodemon app.js
[nodemon] 2.0.2
[nodemon] to restart at any time, enter rs
[nodemon] watching dir(s): .
[nodemon] watching extensions: js,mjs,json
[nodemon] starting node app.js
admin 123456 //後端拿到了前端傳給的數據``
此時傳過的數據後端會拿他與數據庫做比對,進行處理,而Node.js只充當中介做用,不作數據的處理。
二、咱們接着看,把要的數據傳個服務端,使用axios發送數據到服務端,其中裏面用到了數據格式的轉換:
`const Router = require('koa-router');
const querystring = require('querystring');
const router = new Router();
router.get('/',async ctx=>{
await ctx.render('admin/admin')
})
//此處爲中間層,起到中介做用,會把數據發給後端接口
router.post("/login",async ctx => {
const { username,password } = ctx.request.body; //console.log(username,password); //要數據傳給服務端,使用axios發送數據到服務端 const {data} = await axios({ url:'http://localhost/login/check.php', method:'post', data:{ username, password }, // username=admin&password=123456查詢字符串 //數據格式轉換,前端是個JSON數據格式,後端拿到的是表單數據 transformRequest:[ data =>{ return querystring.stringify(data) } ] })
})
module.exports = router.routes();`
此時登陸頁面輸入用戶名和不一樣的密碼和空密碼時點擊提交時會輸出結構以下代碼:
``^CedzdeMacBook-Pro-5:0323 edz$ nodemon app.js
[nodemon] 2.0.2
[nodemon] to restart at any time, enter rs
[nodemon] watching dir(s): .
[nodemon] watching extensions: js,mjs,json
[nodemon] starting node app.js
{ code:1 }
{ code:0 }
{ code:3 }``
三、這時咱們把後端傳回的接口數據在進行從新包裝一下,添加以下代碼:
`// 從新包裝
if(data.code !== 1){ // return中斷條件 return ctx.body = { code:401, message:'未經受權' } } // 前端本身定義的提示語 ,後端專一邏輯開發,不用在和前端定義接口 ctx.body = { code:200, message:'校驗成功' }`
這時頁面會返回通過前端包裝的提示語,如圖所示:
總的處理路由的admin.js代碼文件以下:
`const Router = require('koa-router');
const axios = require('axios');
const querystring = require('querystring');
const router = new Router();
router.get('/',async ctx=>{
await ctx.render('admin/admin')
})
//此處爲中間層,起到中介做用,會把數據發給後端接口
router.post("/login",async ctx => {
const { username,password } = ctx.request.body; //console.log(username,password); //要數據傳給服務端,使用axios發送數據到服務端 const {data} = await axios({ url:'http://localhost/login/check.php', //後端提供的一個接口文件 method:'post', data:{ username, password }, // username=admin&password=123456查詢字符串 //數據格式轉換,前端是個JSON數據格式,後端拿到的是表單數據 transformRequest:[ data =>{ return querystring.stringify(data) } ] }) // 從新包裝 // console.log(data); if(data.code !== 1){ // return中斷條件 return ctx.body = { code:401, message:'未經受權' } } // 前端本身定義的提示語 ,後端專一邏輯開發,不用在和前端定義接口 ctx.body = { code:200, message:'校驗成功' }
})
module.exports = router.routes();`
服務端不要暴露太多給用戶信息,不用提示用戶名正確或者密碼錯誤,防止被別人猜,前端根據後端提供的狀態碼從新定義輸出提示內容,對用戶來講特別的友好,不論後端給前端什麼樣的接口內容,前端均可以包裝接口,因此後端只要返回給前端數據就能夠了,接口的定義前端本身能夠進行包裝。
中間層已經爲愈來愈多的大公司所應用,進入中間層後,前端能作的事情愈來愈多,將觸角伸向了服務器,除了先後端分離外,還能作redis緩存,負載均衡策略。另外一方面,不止是Node.js能作中間層,PHP也能夠,由於Node.js是用js寫的,Node.js的生態很成熟,對於前端人員來講,比較容易上手。
Web端的開發團隊是需求鏈中的最上游、數據鏈的下游,不少產品功能都受限於業務接口,中間層提供了一種可能,讓咱們Web前端開發工做有了本身的接口開發能力能夠對接最原始數據,既減小了前端開發中的侷限性,也讓前端團隊在開發過程當中有了更多的想象力,能更好的根據業務須要快速開展項目。
招聘信息
好將來技術團隊正在熱招前端、算法、流媒體後臺開發等各個方向高級開發工程師崗位,你們可掃描下方二維碼或微信搜索關注「好將來技術」,點擊本公衆號「技術招聘」欄目瞭解詳情,歡迎感興趣的夥伴加入咱們!
也許你還想看