node 第十天 原生node封装一个简易的服务器
- 原生node封装一个简易的服务器, 把前面几天的知识揉和起来做一个服务器
- 基础实现, 首页访问, 静态资源服务器, 特定接口封装, 404
app.js服务器入口文件 app.js node app.js即可启动服务器
const { start } = require('./modules/server');
start();
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
};
server.jsserver 启动模块
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 };
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 };
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
};
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
};
config.js其它模块 服务器基本信息配置
module.exports = {root: process.cwd(),host: '127.0.0.1',port: '3008'
};
- 其实这就是node框架express做的事情 封装服务器有着比较繁琐的过程, 这只是一个简单的模型演示, 比如需要封装上传文件的接口, 你可以用到第三方库multiparty, 需要处理ajax跨域, 你可以封装一个前面学的跨域处理函数 :-)
相关文章:
node 第十天 原生node封装一个简易的服务器
原生node封装一个简易的服务器, 把前面几天的知识揉和起来做一个服务器基础实现, 首页访问, 静态资源服务器, 特定接口封装, 404app.js 服务器入口文件 app.js node app.js即可启动服务器 const { start } require(./modules/server); start();require_modules.js 整合模块导…...
php实战案例记录(25)intval函数的用法
在PHP中,intval()函数用于将一个字符串转换为整数。它的语法如下: intval(string $value, int $base 10): int参数说明: $value:要转换的字符串。$base(可选):进制数,默认为10。如…...
laravel框架介绍(二) composer命令下载laravel报错
1.composer命令下载laravel报如下错 : curl error 18 while downloading https://repo.packagist.org/p2/symfony/uid.j son: transfer closed with 3808 bytes remaining to read,具体为 解决方案:执行以下命令切换镜像 >composer con…...
代码签名证书到期了怎么续费?
我们都知道代码签名证书最长期限可以申请3年,但有的首次申请也会申请1年,这种情况下证书到期了就意味着要重新办理,同样的实名验证步骤还需要再走一遍,尤其目前无论是哪种类型的代码签名证书都会有物理硬件,即使交钱实…...
JAVA 同城服务预约家政小程序开发的优势和运营
随着社会节奏的加快,人们对家庭清洁和维护的需求日益增长。为了满足这一需求,JAVA同城服务预约家政小程序应运而生。本文将详细介绍该小程序开发的优势及运营策略,帮助读者更好地了解其价值和潜力。 一、开发优势 方便快捷:用户…...
基于粒子群算法的无人机航迹规划-附代码
基于粒子群算法的无人机航迹规划 文章目录 基于粒子群算法的无人机航迹规划1.粒子群搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用粒子群算法来优化无人机航迹规划。 1.粒子群…...
前端使用qrcodejs2插件实现根据网址生成二维码
实现效果: 实现方法: 1.安装插件 npm install --save qrcodejs2 2.可以全局引入,也可以只在使用的vue文件中引入 import QRCode from qrcodejs2; 3.在vue文件的template中设置放置二维码的div <div id"qrcode"></di…...
A股风格因子看板 (2023.10 第11期)
该因子看板跟踪A股风格因子,该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子,用以分析市场风格切换、组合风格暴露等。 今日为该因子跟踪第11期,指数组合数据截止日2023-09-30,要点如下 近1年A股风格因子检验统…...
anaconda安装python 3.11
最近需要测试gpt researcher项目,gpt researcher项目的环境是3.11,于是用anaconda创建一个虚拟环境,结果报错了: UnsatisfiableError: The following specifications were found to be incompatible with each other:Package xz c…...
问题:EventSource 收不到流数据及 EventSource 的 onmessage 方法为null
文章目录 问题分析问题 在开发时,有用到 EventSource,但是在 new EventSource 的时候,打印 new EventSource 如下: onmessage : null, onerror : null, onopen: f(event)前端...
P2 B+树索引
文章目录 Task1 B树页B树页B树内部结点B树叶子结点 Task2 B树操作Task2 B树插入和搜索的单一值插入单一值搜索单一值 Task2 B树删除 Task3 叶子扫描的迭代器Task4 并行索引 Task1 B树页 B树页 实际上是每个B树页面的标题部分,包含叶子页面和内部页面共享的信息。 …...
爬虫知识之BeautifulSoup库安装及简单介绍
一. 前言 在前面的几篇文章中我介绍了如何通过Python分析源代码来爬取博客、维基百科InfoBox和图片,其文章链接如下: 其中核心代码如下: # coding=utf-8 import urllib import re #下载静态HTML网页 url=http://www.csdn.net/ content = urllib.urlopen(url).read…...
如何有效取代FTP来帮助企业快速传输大文件
在互联网的发展历史上,FTP是一种具有里程碑意义的协议,它最早出现在1971年,是实现网络上文件传输的基础。FTP的优点是简单、稳定、兼容性强,可以在不同的操作系统和平台之间进行文件交换。然而,时代在进步,…...
免登陆积分商城原理
有客户需要免登陆积分商城,研究了一下发现免登陆用途广泛,实现原理也很简单。如果是浏览器无非就是使用fingerprintjs2之类的扩展来实现获取浏览器指纹ID,如果是APP就获取设备唯一标识,然后在使用cryptojs加密来传递到php…...
muduo源码学习base——Atomic(原子操作与原子整数)
Atomic(原子操作与原子整数) 前置知识AtomicIntegerTget()getAndAdd()getAndSet() 关于原子操作实现无锁队列(lock-free-queue) 前置知识 happens-before: 用来描述两个操作的内存可见性 如果操作 X happens-before 操作 Y,那么 X 的结果对于…...
最短路相关笔记
Floyd Floyd 算法,是一种在图中求任意两点间最短路径的算法。 Floyd 算法适用于求解无负边权回路的图。 时间复杂度为 O ( n 3 ) O(n^3) O(n3),空间复杂度 O ( n 2 ) O(n^2) O(n2)。 对于两点 ( i , j ) (i,j) (i,j) 之间的最短路径,有…...
Web前端-Vue2+Vue3基础入门到实战项目-Day5(自定义指令, 插槽, 案例商品列表, 路由入门)
自定义指令 基本使用 自定义指令: 自己定义的指令, 可以封装一些dom操作, 扩展额外功能全局注册// 1. 全局注册指令 Vue.directive(focus, {// inserted 会在 指令所在的元素, 被插入到页面中时触发inserted (el) {// el 就是指令所绑定的元素// console.log(el)el.focus()} …...
mysql json数据类型 相关函数
创建JSON文本的函数 1.JSON_ARRAY(转换json数组) 2.JSON_OBJECT(转换json对象) 3.JSON_QUOTE(转义字符串) 搜索JSON文本的函数 1.JSON_CONTAINS(json当中是否包含指定value) 2.J…...
如何实现前端实时通信(WebSocket、Socket.io等)?
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...
使用 SSSD 进行网络用户身份验证
文章目录 使用 SSSD 进行网络用户身份验证SSSD和Active Directory先决条件、假设和要求软件安装加域 SSSD配置自动创建HOME目录 检查和验证 Kerberos票证已知的问题参考 使用 SSSD 进行网络用户身份验证 SSSD 代表系统安全服务守护程序,它实际上是处理来自各种网络…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
