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

  1. 原生node封装一个简易的服务器, 把前面几天的知识揉和起来做一个服务器
  2. 基础实现, 首页访问, 静态资源服务器, 特定接口封装, 404
  3. app.js 服务器入口文件 app.js node app.js即可启动服务器
const { start } = require('./modules/server');
start();
  1. require_modules.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 启动模块
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 路由模块, 以及接口处理函数对照表
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 接口处理函数模块
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 其它模块, 用于获取媒体文件类型
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 其它模块 服务器基本信息配置
module.exports = {root: process.cwd(),host: '127.0.0.1',port: '3008'
};
  1. 其实这就是node框架express做的事情 封装服务器有着比较繁琐的过程, 这只是一个简单的模型演示, 比如需要封装上传文件的接口, 你可以用到第三方库multiparty, 需要处理ajax跨域, 你可以封装一个前面学的跨域处理函数 :-)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/116254.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搭建Pytorch的GPU环境超详细

效果 1、下载和安装VS2019 https://visualstudio.microsoft.com/zh-hans/vs/older-downloads/ 登录需要用户名和密码 安装后需要联网下载组件的,安装的时候要勾选使用C++的桌面开发 2、下载和安装显卡驱动 查看自己的显卡型号 从英伟达下载和安装最新驱动

Python学习笔记——MYSQL,SQL核心

食用说明&#xff1a;本笔记适用于有一定编程基础的伙伴们。希望有助于各位&#xff01; SQL语言分类 SQL注释 库管理 表管理 数据操作 分组聚合 分页限制 需要注意的是关键字的顺序不可以错乱&#xff0c;否则会报错其中LIMIT关键字的n是指从第n个开始&#xff0c;m是指查…

【Zero to One系列】微服务Hystrix的熔断器集成

前期回顾&#xff1a; 【Zero to One系列】springcloud微服务集成nacos&#xff0c;形成分布式系统 【Zero to One系列】SpringCloud Gateway结合Nacos完成微服务的网关路由 1、hystrix依赖包 首先引入hystrix相关的依赖包&#xff0c;版本方面自己和项目内相对应即可&#…

LeetCode:1402. 做菜顺序(C++)

目录 1402. 做菜顺序 题目描述&#xff1a; 实现代码与解析&#xff1a; 暴力 原理思路&#xff1a; 动态规划 原理思路&#xff1a; 贪心 原理思路&#xff1a; 1402. 做菜顺序 题目描述&#xff1a; 一个厨师收集了他 n 道菜的满意程度 satisfaction &#xff0c;这…

Electron 学习

Electron基本简介 如果你可以建一个网站&#xff0c;你就可以建一个桌面应用程序。Eletron 是一个使用 JavaScript, HTML和 CSS等Web 技术创建原生程序的框架&#xff0c;它负责比较难搞的部分&#xff0c;你只需把精力放在你的应用的核心上即可。 Electron 可以让你使用纯 Jav…

kr第三阶段(二)32 位汇编

编译与链接 环境配置 masm32 masm32 是微软的 masm32 的民间工具集合。该工具集合除了 asm32 本身的汇编器 ml 外还提供了&#xff1a; SDK 对应的函数声明头文件和 lib 库。32 位版本的 link&#xff08;原版本是 16 位&#xff0c;这里的 32 位版本的 link 来自 VC 6.0&a…

OS 处理机调度

目录 处理机调度的层次 高级调度 作业 作业控制块 JCB 作业调度的主要任务 低级调度 中级调度 进程调度 进程调度时机 进程调度任务 进程调度机制 排队器 分派器 上下文切换器 进程调度方式 非抢占调度方式 抢占调度方式 调度算法 处理机调度算法的目标 处理…

嵌入式软件工程师——2025校招专题(一)

说明&#xff1a; 面试题来源于网络书籍&#xff0c;公司题目以及博主原创或修改&#xff08;题目大部分来源于各种公司&#xff09;&#xff1b;文中很多题目&#xff0c;或许大家直接编译器写完&#xff0c;1分钟就出结果了。但在这里博主希望每一个题目&#xff0c;大家都要…

2023-10-24 小总结

起始 不知不觉&#xff0c;作为职业码农&#xff0c;已经过去了4年。第4个1024了。 期间和Java、C#、JavaScript都打过交道。他们都很优秀。自然&#xff0c;好刀要在强者手中才能熠熠生辉。 快30了&#xff0c;回首过去&#xff0c;很感慨。发生了很多事&#xff0c;很多我都…

Python桌面应用之XX学院水卡报表查询系统(Tkinter+cx_Oracle)

一、功能样式 Python桌面应用之XX学院水卡报表查询系统功能&#xff1a; 连接Oracle数据库&#xff0c;查询XX学院水卡操作总明细报表&#xff0c;汇总数据报表&#xff0c;个人明细报表&#xff0c;进行预览并且支持导出报表 1.总明细报表样式 2.汇总明细样式 3.个人明细…

安卓使用android studio跨进程通信之AIDL

我写这篇文章不想从最基础的介绍开始,我直接上步骤吧. 1.创建服务端 1.1:创建服务端项目:我的as版本比较高,页面就是这样的 1.2:创建AIDL文件,右键项目,选中aidl aidl名字可以自定义也可以默认 basicTypes是自带的,可以删掉,也可以不删,然后把你自己所需的接口写上去 1.3:创建…

微信小程序开发之后台数据交互及wxs应用

目录 一.后端准备 1.1. 应用配置 1.2. 数据源配置 二、数据库 2.1. 创建 2.2.数据表 2.3.数据测试 三、前端 3.1.请求方法整合 3.2.数据请求 3.3.WXS的使用 3.4.样式美化 3.5. 页面 今天就到这里了哦&#xff0c;希望能帮到你哦&#xff01;&#xff01;&#xf…

解密Java中神奇的Synchronized关键字

文章目录 &#x1f389; 定义&#x1f389; JDK6以前&#x1f389; 偏向锁和轻量级锁&#x1f4dd; 偏向锁&#x1f4dd; 轻量级锁&#x1f4dd; 自旋锁&#x1f4dd; 重量级锁&#x1f525; 1. 加锁&#x1f525; 2. 等待&#x1f525; 3. 撤销 &#x1f389; 锁优化&#x1f…

红队打靶:Misdirection打靶思路详解(vulnhub)

目录 写在开头 第一步&#xff1a;主机发现与端口扫描 第二步&#xff1a;Web渗透&#xff08;80端口&#xff0c;战术放弃&#xff09; 第三步&#xff1a;Web渗透&#xff08;8080端口&#xff09; 第四步&#xff1a;sudo bash提权 第五步&#xff1a;/etc/passwd利…

一文搞懂UART通信协议

目录 1、UART简介 2、UART特性 3、UART协议帧 3.1、起始位 3.2、数据位 3.3、奇偶校验位 3.4、停止位 4、UART通信步骤 1、UART简介 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff0c;通用异步收发器&#xff09;是一种双向、串行、异步的通信…

【c++Leetcode】141. Linked List Cycle

问题入口 思想&#xff1a;Floyds Tortoise and Hare 这个算法简单来说就是设置一个慢指针&#xff08;一次移动一个位置&#xff09;和一个快指针&#xff08;一次移动两个位置&#xff09;。在遍历过程中&#xff0c;如果慢指针和快指针都指向同一个元素&#xff0c;证明环…

spacy.load(“en_core_web_trf“)报错TypeError: issubclass() arg 1 must be a class

使用spacy时遇到的问题 写在最前面&#xff1a; 安装spacy和en_core_web_trf时需要保证二者版本一致 安装及查看对应spacy版本 安装 pip install spacy查看版本 import spacy spacy.__version__安装en_core_web_trf 直接安装&#xff08;如果可以的话&#xff09; pytho…

Flutter视图原理之StatefulWidget,InheritedWidget

目录 StatefulElement1. 构造函数2. build3. _firstBuild3. didChangeDependencies4. setState InheritedElement1. Element类2. _updateInheritance3. InheritedWidget数据向下传递3.1 dependOnInheritedWidgetOfExactType 4. InheritedWidget的状态绑定4.1. ProxyElement 在f…

SettingsProvider

Android Settings 系列文章&#xff1a; Android Settings解析SettingsIntelligenceSettingsProvider 首语 为啥要聊到这个模块呢&#xff1f;因为Settings里存在大量的设置项&#xff0c;这些设置项的状态需要保存&#xff0c;它们就是通过SettingsProvider来处理的。以状态…

.net6部署到linux上(CentOS Linux 7)

目录 一、先在linux上配置.net环境 添加 Microsoft 包存储库 安装 SDK 安装运行时 检查 SDK 版本可使用终端查看当前安装的 .NET SDK 版本。 打开终端并运行以下命令。 二、创建.net6 mvc项目 并发布 创建项目 修改默认端口 打包发布到文件夹 运行打包项目查看项目是否…