日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Node第二彈:Node服務(wù)端應(yīng)用路由解析

大家好,我是山月。在上篇文章介紹了 HTTP 報文及簡單的服務(wù)端框架要素,如如何接受請求參數(shù)等。這篇文章介紹另一個常見的主題:路由。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名與空間、網(wǎng)頁空間、營銷軟件、網(wǎng)站建設(shè)、上高網(wǎng)站維護(hù)、網(wǎng)站推廣。

簡單路由

最簡單的路由可使用 req.url 進(jìn)行路由分發(fā)不同的邏輯,代碼如下所示。

但是對于一個非Demo式的頁面,業(yè)務(wù)邏輯都堆在一起,這顯得太為簡陋。

 
 
 
 
  1. const http = require('http')
  2. const server = http.createServer((req, res) => {
  3.   console.log(req.url)
  4.   let data = ''
  5.   if (req.url === '/') {
  6.     data = 'hello, world'
  7.     res.end(data)
  8.   } else if (req.url === '/json') {
  9.     res.setHeader('Content-Type', 'application/json; charset=utf-8');
  10.     data = JSON.stringify({ username: '山月' })
  11.     res.end(data)
  12.   } else if (req.url === '/input') {
  13.     let body = ''
  14.     req.on('data', chunk => body += chunk)
  15.     req.on('end', () => {
  16.       data = body
  17.       res.end(data)
  18.     })
  19.   }
  20.   
  21. })
  22. server.listen(3000)

復(fù)雜路由

作為一個能夠在生產(chǎn)環(huán)境使用,較為復(fù)雜的路由至少能夠解析以下路由,并為單獨路由配置單獨的業(yè)務(wù)邏輯處理函數(shù)

 
 
 
 
  1. Method: app.post('/', handler)
  2. Param Path: app.post('/users/:userId', handler)

基于正則路由

目前,絕大部分服務(wù)端框架的路由都是基于正則進(jìn)行匹配,如 koa、express 等。另外,前端框架的路由 vue-router 與 react-router 也是基于正則匹配。

而這些框架基于正則匹配的路由,都離不開一個庫: path-to-regexp,它將把一個路由如 /user/:name 轉(zhuǎn)化為正則表達(dá)式。

https://github.com/pillarjs/path-to-regexp

標(biāo)題:path-to-regexp

它的 API 十分簡單:

  • pathToRegexp: 可將路由轉(zhuǎn)化為正則表達(dá)式
  • match: 可匹配參數(shù)
 
 
 
 
  1. const { pathToRegexp, match, parse, compile } = require('path-to-regexp')
  2. pathToRegexp('/api/users/:userId')
  3. //=> /^\/api\/users(?:\/([^\/#\?]+?))[\/#\?]?$/i
  4. const toParams = match('/api/users/:userId')
  5. toParams('/api/users/10')
  6. //=> {
  7. //   index: 0
  8. //   params: {userId: "12"}
  9. //   path: "/api/users/12"
  10. // }

那這些 Node 服務(wù)器框架基于正則路由的原理是什么?

  • 注冊路由。每一個路由都作為一個 Layer (在 express、koa 中),并使用 path-to-regexp 把路由路徑轉(zhuǎn)化為正則,作為 Layer 的屬性。
  • 匹配路由。當(dāng)一次請求來臨時,對比路由表中每一條路由,找到匹配正則的多條路由,執(zhí)行多條路由所對應(yīng)的業(yè)務(wù)處理邏輯。

從上可以看出它沒進(jìn)行一次路由匹配的時間復(fù)雜度為: 「O(n) X 正則匹配復(fù)雜度」

基于正則路由的一些問題

性能問題先不談,先看一個問題:

「當(dāng)我們請求 /api/users/10086,有兩條路由可供選擇: /api/users/10086 與 /api/users/:userId,此時將會匹配哪一條路由?」

以下是由 koa/koa-router 書寫, 「由于是正則匹配,此時極易出現(xiàn)路由沖突問題,匹配路由時與順序極為相關(guān)?!?/p>

 
 
 
 
  1. const Koa = require("koa");
  2. const Router = require("@koa/router");
  3. const app = new Koa();
  4. const router = new Router();
  5. router.get("/api/users/10086", (ctx, next) => {
  6.   console.log(ctx.router);
  7.   ctx.body = {
  8.     userId: 10086,
  9.     direct: true
  10.   };
  11. });
  12. router.get("/api/users/:userId", (ctx, next) => {
  13.   console.log(ctx.router);
  14.   ctx.body = {
  15.     userId: ctx.params.userId
  16.   };
  17. });

基于前綴樹路由 (Trie、Radix Tree、Prefix Tree)

相對于正則匹配路由而言,基于前綴樹匹配更加高效,且無上述路由沖突問題。

  • find-my-way

https://github.com/delvedor/find-my-way

標(biāo)題:find-my-way

 
 
 
 
  1. const http = require('http')
  2. const router = require('find-my-way')()
  3. const server = http.createServer((req, res) => {
  4.   router.lookup(req, res)
  5. })
  6. router.on('GET', '/api', () => {})
  7. router.on('GET', '/api/users/:id', (req, res) => { res.end('id') })
  8. router.on('GET', '/api/users/10086', (req, res) => { res.end('10086') })
  9. router.on('GET', '/api/users-friends', () => {})
  10. console.log(router.prettyPrint())
  11. server.listen(3000)

在上述代碼中,將把所有路由路徑構(gòu)成前綴樹。前綴樹,顧名思義,將會把字符串的公共前綴提取出來。

 
 
 
 
  1. └── /api (GET)
  2.     └── /users
  3.         ├── /
  4.         │   ├── 10086 (GET)
  5.         │   └── :id (GET)
  6.         └── -friends (GET)

可以看出,前綴樹路由的匹配時間復(fù)雜度明顯小于 O(n),且每次不會有正則路由進(jìn)行正則匹配的復(fù)雜度。這決定了它相比正則路由更高的性能。

Node 中最快的框架 fastify,便是內(nèi)置了基于前綴樹的路由。

 
 
 
 
  1. const fastify = require('fastify')()
  2. fastify.get('/api/users/10086', async (request, reply) => {
  3.   return { userId: 10086, direct: true }
  4. })
  5. fastify.get('/api/users/:id', async (request, reply) => {
  6.   const id = request.params.id
  7.   return { userId: id }
  8. })
  9. fastify.listen(3000)

405

在 HTTP 狀態(tài)碼中,與路由相關(guān)的狀態(tài)碼為 404、405,作為一個專業(yè)的路由庫,實現(xiàn)一個 405 也是分內(nèi)之事。

  • 301
  • 302
  • 307
  • 308
  • 404: Not Found
  • 405: Method Not Allowed

嗯,代碼就不放了... 本文轉(zhuǎn)載自微信公眾號「全棧成長之路」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系全棧成長之路公眾號。


分享文章:Node第二彈:Node服務(wù)端應(yīng)用路由解析
本文URL:http://www.5511xx.com/article/ccdhihg.html