当前位置: 首页 > news >正文

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跨域, 你可以封装一个前面学的跨域处理函数 :-)

相关文章:

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

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

php实战案例记录(25)intval函数的用法

在PHP中&#xff0c;intval()函数用于将一个字符串转换为整数。它的语法如下&#xff1a; intval(string $value, int $base 10): int参数说明&#xff1a; $value&#xff1a;要转换的字符串。$base&#xff08;可选&#xff09;&#xff1a;进制数&#xff0c;默认为10。如…...

laravel框架介绍(二) composer命令下载laravel报错

1.composer命令下载laravel报如下错 &#xff1a; curl error 18 while downloading https://repo.packagist.org/p2/symfony/uid.j son: transfer closed with 3808 bytes remaining to read&#xff0c;具体为 解决方案&#xff1a;执行以下命令切换镜像 >composer con…...

代码签名证书到期了怎么续费?

我们都知道代码签名证书最长期限可以申请3年&#xff0c;但有的首次申请也会申请1年&#xff0c;这种情况下证书到期了就意味着要重新办理&#xff0c;同样的实名验证步骤还需要再走一遍&#xff0c;尤其目前无论是哪种类型的代码签名证书都会有物理硬件&#xff0c;即使交钱实…...

JAVA 同城服务预约家政小程序开发的优势和运营

随着社会节奏的加快&#xff0c;人们对家庭清洁和维护的需求日益增长。为了满足这一需求&#xff0c;JAVA同城服务预约家政小程序应运而生。本文将详细介绍该小程序开发的优势及运营策略&#xff0c;帮助读者更好地了解其价值和潜力。 一、开发优势 方便快捷&#xff1a;用户…...

基于粒子群算法的无人机航迹规划-附代码

基于粒子群算法的无人机航迹规划 文章目录 基于粒子群算法的无人机航迹规划1.粒子群搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用粒子群算法来优化无人机航迹规划。 1.粒子群…...

前端使用qrcodejs2插件实现根据网址生成二维码

实现效果&#xff1a; 实现方法&#xff1a; 1.安装插件 npm install --save qrcodejs2 2.可以全局引入&#xff0c;也可以只在使用的vue文件中引入 import QRCode from qrcodejs2; 3.在vue文件的template中设置放置二维码的div <div id"qrcode"></di…...

A股风格因子看板 (2023.10 第11期)

该因子看板跟踪A股风格因子&#xff0c;该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子&#xff0c;用以分析市场风格切换、组合风格暴露等。 今日为该因子跟踪第11期&#xff0c;指数组合数据截止日2023-09-30&#xff0c;要点如下 近1年A股风格因子检验统…...

anaconda安装python 3.11

最近需要测试gpt researcher项目&#xff0c;gpt researcher项目的环境是3.11&#xff0c;于是用anaconda创建一个虚拟环境&#xff0c;结果报错了&#xff1a; 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树页面的标题部分&#xff0c;包含叶子页面和内部页面共享的信息。 …...

爬虫知识之BeautifulSoup库安装及简单介绍

一. 前言 在前面的几篇文章中我介绍了如何通过Python分析源代码来爬取博客、维基百科InfoBox和图片,其文章链接如下: 其中核心代码如下: # coding=utf-8 import urllib import re #下载静态HTML网页 url=http://www.csdn.net/ content = urllib.urlopen(url).read…...

如何有效取代FTP来帮助企业快速传输大文件

在互联网的发展历史上&#xff0c;FTP是一种具有里程碑意义的协议&#xff0c;它最早出现在1971年&#xff0c;是实现网络上文件传输的基础。FTP的优点是简单、稳定、兼容性强&#xff0c;可以在不同的操作系统和平台之间进行文件交换。然而&#xff0c;时代在进步&#xff0c;…...

免登陆积分商城原理

有客户需要免登陆积分商城&#xff0c;研究了一下发现免登陆用途广泛&#xff0c;实现原理也很简单。如果是浏览器无非就是使用fingerprintjs2之类的扩展来实现获取浏览器指纹ID&#xff0c;如果是APP就获取设备唯一标识&#xff0c;然后在使用cryptojs加密来传递到php&#xf…...

muduo源码学习base——Atomic(原子操作与原子整数)

Atomic(原子操作与原子整数&#xff09; 前置知识AtomicIntegerTget()getAndAdd()getAndSet() 关于原子操作实现无锁队列(lock-free-queue) 前置知识 happens-before&#xff1a; 用来描述两个操作的内存可见性 如果操作 X happens-before 操作 Y&#xff0c;那么 X 的结果对于…...

最短路相关笔记

Floyd Floyd 算法&#xff0c;是一种在图中求任意两点间最短路径的算法。 Floyd 算法适用于求解无负边权回路的图。 时间复杂度为 O ( n 3 ) O(n^3) O(n3)&#xff0c;空间复杂度 O ( n 2 ) O(n^2) O(n2)。 对于两点 ( i , j ) (i,j) (i,j) 之间的最短路径&#xff0c;有…...

Web前端-Vue2+Vue3基础入门到实战项目-Day5(自定义指令, 插槽, 案例商品列表, 路由入门)

自定义指令 基本使用 自定义指令: 自己定义的指令, 可以封装一些dom操作, 扩展额外功能全局注册// 1. 全局注册指令 Vue.directive(focus, {// inserted 会在 指令所在的元素, 被插入到页面中时触发inserted (el) {// el 就是指令所绑定的元素// console.log(el)el.focus()} …...

mysql json数据类型 相关函数

创建JSON文本的函数 1.JSON_ARRAY&#xff08;转换json数组&#xff09; 2.JSON_OBJECT&#xff08;转换json对象&#xff09; 3.JSON_QUOTE&#xff08;转义字符串&#xff09; 搜索JSON文本的函数 1.JSON_CONTAINS&#xff08;json当中是否包含指定value&#xff09; 2.J…...

如何实现前端实时通信(WebSocket、Socket.io等)?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

使用 SSSD 进行网络用户身份验证

文章目录 使用 SSSD 进行网络用户身份验证SSSD和Active Directory先决条件、假设和要求软件安装加域 SSSD配置自动创建HOME目录 检查和验证 Kerberos票证已知的问题参考 使用 SSSD 进行网络用户身份验证 SSSD 代表系统安全服务守护程序&#xff0c;它实际上是处理来自各种网络…...

STPopup键盘处理详解:智能避让和自动重定位的终极解决方案

STPopup键盘处理详解&#xff1a;智能避让和自动重定位的终极解决方案 【免费下载链接】STPopup STPopup provides STPopupController, which works just like UINavigationController in popup style, for both iPhone and iPad. Its written in Objective-C and compatible w…...

实测实在Agent:打破“龙虾”落地僵局,科普Agent如何进化为企业级数字员工?

摘要&#xff1a; 站在2026年4月的技术拐点&#xff0c;以“龙虾”&#xff08;OpenClaw&#xff09;为代表的科普Agent已从极客圈的“命令行玩具”演变为产业界的“执行力支柱”。然而&#xff0c;在企业级落地过程中&#xff0c;API缺失导致的“系统围墙”、信创环境下的适配…...

3个关键步骤:如何安全备份微信聊天记录并永久保存你的数字记忆?

3个关键步骤&#xff1a;如何安全备份微信聊天记录并永久保存你的数字记忆&#xff1f; 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾因手机丢失、系统升级或意…...

从ReaxFF产物数量演化到反应动力学参数提取:一个Python脚本的实践

1. ReaxFF模拟与反应动力学分析入门 当你第一次看到LAMMPS的fix reaxff/species输出文件时&#xff0c;可能会被密密麻麻的数据搞得头晕。这些数字背后其实藏着化学反应的全部秘密——就像化学反应的"黑匣子飞行记录仪"。我在分析酯类热解反应时&#xff0c;花了整整…...

东南大学论文模板终极指南:告别格式烦恼,专注学术创作

东南大学论文模板终极指南&#xff1a;告别格式烦恼&#xff0c;专注学术创作 【免费下载链接】SEUThesis 项目地址: https://gitcode.com/gh_mirrors/seu/SEUThesis 每到毕业季&#xff0c;无数东南大学学子都面临同样的困境——花费数周时间反复调整论文格式&#xf…...

Qwen2.5-0.5B-Instruct实战:Python调用接口代码实例

Qwen2.5-0.5B-Instruct实战&#xff1a;Python调用接口代码实例 想快速上手一个轻量级但功能强大的AI模型吗&#xff1f;今天我们来聊聊阿里开源的Qwen2.5-0.5B-Instruct模型&#xff0c;并手把手教你如何用Python调用它的接口。这个模型虽然参数只有5亿&#xff0c;但在指令遵…...

GoJieba自定义词典使用指南:3步添加专业领域词汇的终极方法

GoJieba自定义词典使用指南&#xff1a;3步添加专业领域词汇的终极方法 【免费下载链接】gojieba "结巴"中文分词的Golang版本 项目地址: https://gitcode.com/gh_mirrors/go/gojieba GoJieba是"结巴"中文分词的Golang版本&#xff0c;作为一款高效…...

Pixel Language Portal入门必看:基于Hunyuan-MT-7B的怀旧风翻译工具从零搭建

Pixel Language Portal入门必看&#xff1a;基于Hunyuan-MT-7B的怀旧风翻译工具从零搭建 1. 项目介绍与核心价值 Pixel Language Portal&#xff08;像素语言跨维传送门&#xff09;是一款融合了复古游戏美学与现代AI翻译技术的创新工具。与传统翻译软件不同&#xff0c;它将…...

AudioSeal实战案例:无障碍AI语音服务中水印与无障碍元数据共存方案

AudioSeal实战案例&#xff1a;无障碍AI语音服务中水印与无障碍元数据共存方案 1. 项目背景与价值 在AI语音服务快速发展的今天&#xff0c;如何平衡内容保护与无障碍访问成为一个重要课题。AudioSeal作为Meta开源的语音水印系统&#xff0c;为解决这一问题提供了创新方案。 …...

如何通过EhViewer实现安卓画廊资源高效管理与无缝阅读体验?

如何通过EhViewer实现安卓画廊资源高效管理与无缝阅读体验&#xff1f; 【免费下载链接】EhViewer &#x1f965; A fork of EhViewer, feature requests are not accepted. Forked from https://gitlab.com/NekoInverter/EhViewer 项目地址: https://gitcode.com/GitHub_Tre…...