node 第十天 原生node封装一个简易的服务器

  1. 原生node封装一个简易的服务器, 把前面几天的知识揉和起来做一个服务器
  2. 基础实现, 首页访问, 静态资源服务器, 特定接口封装, 404
  3. app.js 服务器入口文件 app.js node app.js即可启动服务器
js 复制代码
const { start } = require('./modules/server');
start();
  1. require_modules.js 整合模块导出
js 复制代码
const url = require('url');
const path = require('path');
const http = require('http');
const querystring = require('querystring');
const fs = require('fs');
const multiparty = require('multiparty');

module.exports = {
  url,
  path,
  http,
  querystring,
  fs,
  multiparty
};
  1. server.js server 启动模块
js 复制代码
const { http } = require('./require_modules');
const { port, host } = require('./config');
const { route } = require('./router');

function start() {
  const server = http.createServer((req, res) => {
    route(req, res);
  });
  server.listen(port, host, () => {
    console.log(`server listening in http://${host}:${port}`);
  });
}
module.exports = { start };
  1. router.js 路由模块, 以及接口处理函数对照表
js 复制代码
const { url } = require('./require_modules');
const { host, port } = require('./config');
const { staticHanlder, indexHanlder, tableHanlder, notFind } = require('./hanlder');
const hanlder = {
  '/index': indexHanlder,
  '/static': staticHanlder,
  '/index': indexHanlder,
  '/getTableData': tableHanlder,
  404: notFind
};
const route = (req, res) => {
  const thisURL = new URL(`http://${host}:${port}${req.url}`);
  let pathname = thisURL.pathname;
  if (pathname === '/') {
    pathname = '/index/';
  }
  const thisHanlder =
    Object.entries(hanlder).find(([key, val]) => {
      let reg = new RegExp(`^${key}/.*`);
      return reg.test(pathname);
    })?.[1] ?? hanlder[404];

  thisHanlder(req, res, pathname);
};
module.exports = { route };
  1. hanlder.js 接口处理函数模块
js 复制代码
const { fs, path, querystring } = require('../modules/require_modules');
const { getMimeType } = require('../modules/mime_type');
const { root } = require('./config');
const { host, port } = require('./config');

function staticHanlder(req, res, pathname) {
  res.writeHeader(200, { 'content-type': getMimeType(pathname) });

  const filePath = path.join(root, pathname);

  fs.stat(filePath, (err, stats) => {
    if (err) {
      notFind(req, res, pathname);
      return;
    }
    if (!stats) {
      notFind(req, res, pathname);
      return;
    }
    if (stats.isDirectory()) {
      notFind(req, res, pathname);
      return;
    }
    if (stats.isFile()) {
      fs.readFile(filePath, (err, data) => {
        if (err) {
          notFind(req, res, pathname);
        }
        res.writeHeader(200, { 'content-type': getMimeType(pathname) });
        res.end(data);
      });
      return;
    }
  });
}
function indexHanlder(req, res, pathname) {
  res.writeHeader(200, { 'content-type': 'text/html;charset=utf-8' });
  res.end(`<!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>index</title>
    </head>
    <body>
      <h1>欢迎~</h1>
    </body>
  </html>`);
}
function tableHanlder(req, res, pathname) {
  const thisURL = new URL(`http://${host}:${port}${req.url}`);
  let search = thisURL.search.replace('?', '');
  const searchInfo = querystring.parse(search);
  let start = Number(searchInfo.start) || 0;
  let end = Number(searchInfo.end) || start + 10;
  const jsonPath = path.join(root, '/data/table.json');
  fs.readFile(jsonPath, (err, data) => {
    if (err) {
      notFind(req, res, pathname);
      return;
    }
    const jsonData = JSON.parse(data.toString('utf-8'));
    const resData = jsonData.slice(start, end);
    res.writeHeader(200, { 'content-type': 'application/json;charset=utf-8' });
    res.end(JSON.stringify(resData));
  });
}

function notFind(req, res, pathname) {
  res.writeHeader(404, { 'content-type': 'text/html;charset=utf-8' });
  res.end(`<!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>404</title>
    </head>
    <body>
      <h1>not find</h1>
    </body>
  </html>`);
}
function serverError(req, res, pathname) {
  res.writeHeader(500, { 'content-type': 'text/html;charset=utf-8' });
  res.end(`<!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>500</title>
    </head>
    <body>
      <h1>server error</h1>
    </body>
  </html>`);
}
module.exports = {
  staticHanlder,
  indexHanlder,
  tableHanlder,
  notFind,
  serverError
};
  1. mime_type.js 其它模块, 用于获取媒体文件类型
js 复制代码
const { path } = require('../modules/require_modules');
const MIME_TYPE = {
  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'
};

function getMimeType(pathname) {
  let ext = path.extname(pathname).replace('.', '').toLowerCase();
  if (!ext) {
    ext = pathname;
  }
  return MIME_TYPE[ext] || MIME_TYPE['txt'];
}
module.exports = {
  getMimeType
};
  1. config.js 其它模块 服务器基本信息配置
js 复制代码
module.exports = {
  root: process.cwd(),
  host: '127.0.0.1',
  port: '3008'
};
  1. 其实这就是node框架express做的事情 封装服务器有着比较繁琐的过程, 这只是一个简单的模型演示, 比如需要封装上传文件的接口, 你可以用到第三方库multiparty, 需要处理ajax跨域, 你可以封装一个前面学的跨域处理函数 :-)
相关推荐
耶啵奶膘19 分钟前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^2 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie2 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic3 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿3 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具4 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
清灵xmf4 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
小白学大数据4 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
qq_390161774 小时前
防抖函数--应用场景及示例
前端·javascript
334554325 小时前
element动态表头合并表格
开发语言·javascript·ecmascript