摘要:了解原理之前,你需要先掌握的基本用法。基本結構先回顧一下使用的的過程,首先是把模塊倒入,然后當做方法執行,在返回值中調用處理路由,調用監聽端口。大多數中間件也是這個原理,如模塊,給它加個屬性即可。
了解 express 原理之前,你需要先掌握 express 的基本用法。
關于 express 的介紹請看 express 官網。
基本結構先回顧一下 express 使用的的過程,首先是把模塊倒入,然后當做方法執行,在返回值中調用 use 處理路由,調用 listen 監聽端口。
const express = require("express") const app = express() app.use("/home", (req, res) => { res.end("home") }) app.listen(8080, () => { console.log("port created successfully") })
根據上面的使用,我們開始構建代碼。我們需要寫一個 express 方法,返回一個 app 對象,有 use 和 listen 方法。
const http = require("http") const url = require("url") function express() { const app = {} const routes = []; app.use = function (path, action) { routes.push([path, action]) } function handle(req, res) { let pathname = url.parse(req.url).pathname; for (let i = 0; i < routes.length; i++) { var route = routes[i]; if (pathname === route[0]) { let action = route[1]; action(req, res); return; } } handle404(req, res); } function handle404(req, res) { res.end("404") } app.listen = function (...args) { const server = http.createServer((req, res) => { handle(req, res) }) server.listen(...args) } return app } module.exports = express
上面代碼中的 use 方法的作用是把請求路徑跟對應的處理函數存放在一個數組中,當請求到來的時候遍歷數組,根據路徑找到對應的方法執行。
動態路由動態路由是根據參數可以動態匹配路徑。
const express = require("./express") const app = express() // /home/1 // /home/2 app.use("/home/:id", (req, res) => { res.end("home") }) app.listen(8080, () => { console.log("port created successfully") })
根據路由里面的參數要匹配符合規則的路由我們需要使用正則來處理,下面代碼是根據路徑來生成正則的一個方法。
const pathRegexp = (path, paramNames=[], {end=false} ={}) => { path = path .concat(end ? "" : "/?") .replace(//(/g, "(?:/") .replace(/(/)?(.)?:(w+)(?:((.*?)))?(?)?(*)?/g, function (_, slash, format, key, capture, optional, star) { slash = slash || ""; paramNames.push(key); return "" + (optional ? "" : slash) + "(?:" + (optional ? slash : "") + (format || "") + (capture || (format && "([^/.]+?)" || "([^/]+?)")) + ")" + (optional || "") + (star ? "(/*)?" : ""); }) .replace(/([/.])/g, "$1") .replace(/*/g, "(.*)"); return new RegExp("^" + path + "$") } module.exports = pathRegexp
根據路徑生成正則也是有第三方模塊 path-to-regexp 模塊,核心原理大家值得參考。包括 Vue 和 React 的路由都使用到了這個模塊。
下面我們需要開始動態映射路由。
const http = require("http") const url = require("url") const pathRegexp = require("./pathRegexp") function express() { const app = {} const routes = { "all": [] }; app.use = function (path, action) { const keys = [] const regexp = pathRegexp(path, keys,{end:true}) routes.all.push([ { regexp, keys }, action ]); }; ["get", "put", "delete", "post"].forEach(function (method) { routes[method] = []; app[method] = function (path, action) { const keys = [] const regexp = pathRegexp(path, keys, {end:true}) routes[method].push([ { regexp, keys }, action ]); }; }); const match = function (pathname, routes, req, res) { for (var i = 0; i < routes.length; i++) { let route = routes[i]; let reg = route[0].regexp; let keys = route[0].keys; let matched = reg.exec(pathname); if (matched) { let params = {}; for (let i = 0, l = keys.length; i < l; i++) { let value = matched[i + 1]; if (value) { params[keys[i]] = value; } } req.params = params; let action = route[1]; action(req, res); return true; } } return false; }; function handle(req, res) { let {pathname, query} = url.parse(req.url, true); req.query = query let method = req.method.toLowerCase(); if (routes.hasOwnProperty(method)) { if (match(pathname, routes[method], req, res)) { return; } else { if (match(pathname, routes.all, req, res)) { return; } } } else { if (match(pathname, routes.all, req, res)) { return; } } handle404(req, res); } function handle404 (req, res) { res.end("404") } app.listen = function (...args) { const server = http.createServer((req, res) => { handle(req, res) }) server.listen(...args) } return app } module.exports = express
其中 express 會把請求的方法都代理到 app 中作為屬性的方式來方便用戶使用。
const express = require("./express") const app = express() app.use("/home/:id", (req, res) => { console.log(req.params) res.end("home") }) // app.get // app.post app.get("/user", (req, res) => { console.log(req.query) res.end("user") }) app.listen(8080, () => { console.log("port created successfully") })
express 會在請求對象中加一些屬性,會把路徑參數作為請求時的 params 屬性,會把查詢字符串作為請求時的 query 屬性。大多數中間件也是這個原理,如 body-parser 模塊,給它加個 body 屬性即可。
通過GitHub查看代碼請點擊:傳送門
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105140.html
摘要:基于以上原因,很多管理都是基于實現的。在經過中間件的時候就會自動完成的有效性驗證延期重新頒發以及對中數據的獲取了。上述代碼只是對于請求的靜態處理,整個用戶管理的另一個方面則是狀態的切換用戶的登陸登出以及用戶數據的獲取。 基礎概念 Session管理是Web Application的基礎也是一個老生常談的話題。為了方便后文的展開,更重要的是確認自己清晰的理解了整個Session管理的概...
摘要:什么是跨域當協議域名端口號,有一個或多個不同時,有希望可以訪問并獲取數據的現象稱為跨域訪問,同源策略限制下都是不支持跨域的。命名是隨意的,只要是符合一級域名與二級域名的關系即可,然后訪問。 showImg(https://segmentfault.com/img/remote/1460000018998493); 閱讀原文 同源策略 同源策略/SOP(Same origin pol...
摘要:把文件上傳路徑指定到然后用當前日期和文件名命名上傳過來的文件。后端利用建立服務器,利用中間件指定文件路徑。利用這個前端和后端技術,我們基本上就可以做出一個圖片上傳存儲的基本網站核心。 前幾天看了騰訊云社區的一個文件上傳的文章文件上傳那些事兒,大體上講了以下h5中圖片上傳的幾個核心原理,但是沒有后端接受的服務器代碼,沒法做測試。也沒有具體的一個實例都是一些基本的原理片段,并且ui界面也不...
摘要:今天分享一篇公司大佬的文章,非常厲害的大神崇拜臉,講講服務端渲染。服務端渲染,它到底用了什么原理呢服務端渲染原理服務端渲染的方式有很多,主流的服務端語言為使用渲染。 富婆來報道,今天想問題想不出來,隨手抓了一下頭發,沒想到啊沒想到,我那濃(mei)密(sheng)茂(ji)盛(gen)的秀發又少了好幾根,一定要改掉這個想不出來問題就揪頭發的壞習慣。今天分享一篇公司大佬的文章,非常厲害的...
閱讀 2754·2019-08-30 15:53
閱讀 521·2019-08-29 17:22
閱讀 1040·2019-08-29 13:10
閱讀 2307·2019-08-26 13:45
閱讀 2751·2019-08-26 10:46
閱讀 3201·2019-08-26 10:45
閱讀 2504·2019-08-26 10:14
閱讀 467·2019-08-23 18:23