资讯专栏INFORMATION COLUMN

express简单实现

Mertens / 1788人阅读

摘要:框架实现将所有请求方式写入对象中匹配剩余路由中间件服务循环路由,匹配到就执行它的函数用函数匹配中间件匹配一般路由静态资源服务中间价实现使用

express 框架实现
const http = require("http");
const url = require("url");

function createApp() {
  var app = {};
  var routes = [];

  // 将所有请求方式写入app对象中
  http.METHODS.forEach(method => {
    method = method.toLocaleLowerCase();
    app[method] = (path, handler) => {
      let route = {
        path,
        method,
        handler
      };
      routes.push(route);
    };
  });

  // 匹配剩余路由
  app.all = (path, handler) => {
    let route = {
      method: "all",
      path,
      handler
    };
    routes.push(route);
  };

  // 中间件
  app.use = (path, handler) => {
    if(handler === undefined) {
      handler = path;
      path = "/";
    }

    let route = {
      method: "middle",
      path,
      handler,
    }

    routes.push(route);
  }

  // 服务
  let server = http.createServer((req, res) => {
    let method = req.method.toLocaleLowerCase();
    let { pathname } = url.parse(req.url, true);
    pathname = decodeURI(pathname);
    // 循环路由,匹配到就执行它的handler函数
    // 用next函数
    let i = 0;

    let next = () => {
      if(i >= routes.length) return;
      let { method: m, path: p, handler: h } = routes[i];
      i++;
      if(m === "middle") {
        // 匹配中间件
        if(p == "/" || p == pathname || pathname.startsWith(p+"/")) {
          h(req, res, next);
        } else {
          next();
        }
      } else {
        // 匹配一般路由
        if ((m == method || m == "all") && (p == pathname || p === "*")) {
          h(req, res);
        } else {
          next();
        }
      }
    }

    next();
  });

  app.listen = (...rest) => {
    server.listen(...rest);
  };

  return app;
}

module.exports = createApp;
静态资源服务中间价实现
const path = require("path");
const fs = require("fs");
const url = require("url");

const mime = {
  css: "text/css",
  gif: "image/gif",
  html: "text/html",
  ico: "image/x-icon",
  jpeg: "image/jpeg",
  jpg: "image/jpeg",
  js: "text/javascript",
  json: "application/json",
  pdf: "application/pdf",
  png: "image/png",
  svg: "image/svg+xml",
  swf: "application/x-shockwave-flash",
  tiff: "image/tiff",
  txt: "text/plain",
  wav: "audio/x-wav",
  wma: "audio/x-ms-wma",
  wmv: "video/x-ms-wmv",
  xml: "text/xml",
  unknown: "text/plain"
};

function static(basename) {
    return (req, res, next) => {
        let { pathname } = url.parse(req.url, true);
        pathname = decodeURI(pathname);
        let p = path.resolve(path.join(basename, pathname));
        fs.stat(p, (err, stats) => {
            if(err) next();
            if(stats && stats.isFile()) {
                let ext = path.extname(p).slice(1);
                res.writeHead(200, {"content-type": `${mime[ext]};charset=utf-8`})
                let rs = fs.createReadStream(p);
                rs.pipe(res);
            } else {
                next();
            }
        })
    }
}

module.exports = static;
使用
const createApp =  require("./app/index");
const static =  require("./app/static");

let app = createApp();

app.use(static("./static"));

app.all("*", (req, res) => {
    res.end("404");
});

app.listen(8080, "127.0.0.1");

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106846.html

相关文章

  • Express + Ejs实现一个简单的WebServer

    摘要:最近在看,读完官方的起步教程后想着该自己折腾点东西,就先用实现一个超简单的,主要记录下思路。先推荐一个入门级的简单实战项目地址。不过鉴于初学,自身的思路肯定不会是最佳实践,慢慢积累。 最近在看node.js,读完官方的起步教程后想着该自己折腾点东西,就先用express + ejs实现一个超简单的webserver,主要记录下思路。先推荐一个nodejs入门级的简单实战项目地址。很适合...

    Tonny 评论0 收藏0
  • Express 实战(五):路由

    摘要:的官方描述是是一个独立于中间件和路由的实例,你可以将看作是只能执行执行中间件和路由的小心应用。最大的不同在于只能已模块形式存在并不能独立运行。另外,加密的公钥也被称为证书。客户端在拿到公钥证书后会向这样的证书颁发机构进行验证。 showImg(https://segmentfault.com/img/remote/1460000010820582); 作为 Express 中的最大特点...

    DevWiki 评论0 收藏0
  • Express 实战(一):概览

    摘要:一个标准性的事件就是年的横空出世。引擎快速处理能力和异步编程风格,让开发者从多线程中解脱了出来。其次,通过异步编程范式将其高并发的能力发挥的淋漓尽致。它也仅仅是一个处理请求并作出响应的函数,并无任何特殊之处。 showImg(https://segmentfault.com/img/remote/1460000010819116); 在正式学习 Express 内容之前,我们有必要从大...

    zhaochunqi 评论0 收藏0
  • Express 实战(七):视图与模板:Pug 和 EJS

    摘要:而框架中最常用的两个视图引擎是和。实际上这些上下文对象就是会在视图中使用到的变量。其实视图缓存并不是缓存视图实际上它缓存的视图路径。根据默认视图引擎将缺少拓展名的视图文件补充完整。实际上存在由不同组织维护的两个不同版本的。 showImg(https://segmentfault.com/img/remote/1460000010821004);前面的内容大都是关于 Express 框...

    wmui 评论0 收藏0
  • node express mongoose简单实现全栈之增删改查

    摘要:作为一个有志向的前端,怎么能不搞搞全栈呢。。。地址欢迎大家多多交流前端技术啊,如果大家喜欢的话,请给我一个小小的哦 作为一个有志向的前端,怎么能不搞搞全(zhuang)栈(bi)呢。。。说搞咱就搞啊,后端就用node,数据库就用mongodb,前端呢,呃,再搞个node的web框架express,思路搞定,开始搭建我们的环境,搭建之前还是先看看我们的目标和成果 项目的目标和成果 sh...

    AndroidTraveler 评论0 收藏0
  • Express 实战(四):中间件

    摘要:调用函数执行下一个中间件函数。然后,该中间件调用函数检查文件是否存在。为了代码更加清晰,你也可以将代码改写为另外,这里在调用函数是使用的是作为输出选项。事实上,中间件有两种类型。 原生 Node 的单一请求处理函数,随着功能的扩张势必会变的越来越难以维护。而 Express 框架则可以通过中间件的方式按照模块和功能对处理函数进行切割处理。这样拆分后的模块不仅逻辑清晰,更重要的是对后期维...

    mochixuan 评论0 收藏0

发表评论

0条评论

Mertens

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<