成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

express基本原理

endiat / 477人閱讀

摘要:了解原理之前,你需要先掌握的基本用法?;窘Y(jié)構(gòu)先回顧一下使用的的過程,首先是把模塊倒入,然后當(dāng)做方法執(zhí)行,在返回值中調(diào)用處理路由,調(diào)用監(jiān)聽端口。大多數(shù)中間件也是這個原理,如模塊,給它加個屬性即可。

了解 express 原理之前,你需要先掌握 express 的基本用法。

關(guān)于 express 的介紹請看 express 官網(wǎng)。

基本結(jié)構(gòu)

先回顧一下 express 使用的的過程,首先是把模塊倒入,然后當(dāng)做方法執(zhí)行,在返回值中調(diào)用 use 處理路由,調(diào)用 listen 監(jiān)聽端口。

const express = require("express")
const app = express()
app.use("/home", (req, res) => {
  res.end("home")
})
app.listen(8080, () => {
  console.log("port created successfully")
})

根據(jù)上面的使用,我們開始構(gòu)建代碼。我們需要寫一個 express 方法,返回一個 app 對象,有 uselisten 方法。

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 方法的作用是把請求路徑跟對應(yīng)的處理函數(shù)存放在一個數(shù)組中,當(dāng)請求到來的時候遍歷數(shù)組,根據(jù)路徑找到對應(yīng)的方法執(zhí)行。

動態(tài)路由

動態(tài)路由是根據(jù)參數(shù)可以動態(tài)匹配路徑。

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")
})

根據(jù)路由里面的參數(shù)要匹配符合規(guī)則的路由我們需要使用正則來處理,下面代碼是根據(jù)路徑來生成正則的一個方法。

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

根據(jù)路徑生成正則也是有第三方模塊 path-to-regexp 模塊,核心原理大家值得參考。包括 Vue 和 React 的路由都使用到了這個模塊。

下面我們需要開始動態(tài)映射路由。

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 會在請求對象中加一些屬性,會把路徑參數(shù)作為請求時的 params 屬性,會把查詢字符串作為請求時的 query 屬性。大多數(shù)中間件也是這個原理,如 body-parser 模塊,給它加個 body 屬性即可。

通過GitHub查看代碼請點(diǎn)擊:傳送門

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105140.html

相關(guān)文章

  • Session原理、安全以及最基本Express和Redis實(shí)現(xiàn)

    摘要:基于以上原因,很多管理都是基于實(shí)現(xiàn)的。在經(jīng)過中間件的時候就會自動完成的有效性驗(yàn)證延期重新頒發(fā)以及對中數(shù)據(jù)的獲取了。上述代碼只是對于請求的靜態(tài)處理,整個用戶管理的另一個方面則是狀態(tài)的切換用戶的登陸登出以及用戶數(shù)據(jù)的獲取。 基礎(chǔ)概念 Session管理是Web Application的基礎(chǔ)也是一個老生常談的話題。為了方便后文的展開,更重要的是確認(rèn)自己清晰的理解了整個Session管理的概...

    Airmusic 評論0 收藏0
  • 九種 “姿勢” 讓你徹底解決跨域問題

    摘要:什么是跨域當(dāng)協(xié)議域名端口號,有一個或多個不同時,有希望可以訪問并獲取數(shù)據(jù)的現(xiàn)象稱為跨域訪問,同源策略限制下都是不支持跨域的。命名是隨意的,只要是符合一級域名與二級域名的關(guān)系即可,然后訪問。 showImg(https://segmentfault.com/img/remote/1460000018998493); 閱讀原文 同源策略 同源策略/SOP(Same origin pol...

    charles_paul 評論0 收藏0
  • 一步一步搭建一個圖片上傳網(wǎng)站(后臺服務(wù)器用nodejs)

    摘要:把文件上傳路徑指定到然后用當(dāng)前日期和文件名命名上傳過來的文件。后端利用建立服務(wù)器,利用中間件指定文件路徑。利用這個前端和后端技術(shù),我們基本上就可以做出一個圖片上傳存儲的基本網(wǎng)站核心。 前幾天看了騰訊云社區(qū)的一個文件上傳的文章文件上傳那些事兒,大體上講了以下h5中圖片上傳的幾個核心原理,但是沒有后端接受的服務(wù)器代碼,沒法做測試。也沒有具體的一個實(shí)例都是一些基本的原理片段,并且ui界面也不...

    Darkgel 評論0 收藏0
  • 干貨實(shí)例:什么是React服務(wù)端渲染?

    摘要:今天分享一篇公司大佬的文章,非常厲害的大神崇拜臉,講講服務(wù)端渲染。服務(wù)端渲染,它到底用了什么原理呢服務(wù)端渲染原理服務(wù)端渲染的方式有很多,主流的服務(wù)端語言為使用渲染。 富婆來報(bào)道,今天想問題想不出來,隨手抓了一下頭發(fā),沒想到啊沒想到,我那濃(mei)密(sheng)茂(ji)盛(gen)的秀發(fā)又少了好幾根,一定要改掉這個想不出來問題就揪頭發(fā)的壞習(xí)慣。今天分享一篇公司大佬的文章,非常厲害的...

    Jason_Geng 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<