亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

express基本原理

endiat / 524人閱讀

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

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

關(guān)于 express 的介紹請(qǐng)看 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)建代碼。我們需要寫一個(gè) express 方法,返回一個(gè) app 對(duì)象,有 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 方法的作用是把請(qǐng)求路徑跟對(duì)應(yīng)的處理函數(shù)存放在一個(gè)數(shù)組中,當(dāng)請(qǐng)求到來的時(shí)候遍歷數(shù)組,根據(jù)路徑找到對(duì)應(yīng)的方法執(zhí)行。

動(dòng)態(tài)路由

動(dòng)態(tài)路由是根據(jù)參數(shù)可以動(dòng)態(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ù)路徑來生成正則的一個(gè)方法。

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 的路由都使用到了這個(gè)模塊。

下面我們需要開始動(dòng)態(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 會(huì)把請(qǐng)求的方法都代理到 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 會(huì)在請(qǐng)求對(duì)象中加一些屬性,會(huì)把路徑參數(shù)作為請(qǐng)求時(shí)的 params 屬性,會(huì)把查詢字符串作為請(qǐng)求時(shí)的 query 屬性。大多數(shù)中間件也是這個(gè)原理,如 body-parser 模塊,給它加個(gè) body 屬性即可。

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/105140.html

相關(guān)文章

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

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

    Airmusic 評(píng)論0 收藏0
  • 九種 “姿勢(shì)” 讓你徹底解決跨域問題

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

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

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

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

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

    Jason_Geng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<