【大前端】使用NodeJs HTTP模块创建web服务器、SSE通讯

Nodejs构建web服务器有很多中方式,常见的有两种:expresshttp.Server

  • express:轻量级的Nodejs web服务器,功能完善,支持自定义插件
  • http.Server:NodeJ内置模块,比express更轻,但需要自己实现请求的处理

本文介绍NodeJs 内置模块http.Server创建Web服务器:

目录结构

shell 复制代码
|_ public # 静态资源目录
	|_ images # 图片资源
		|_ 1.png
	|_ index.html # html 资源
|_ index.js # 服务器

index.js

js 复制代码
const { readFile } = require("fs");
const http = require("http");

// 注意,这里需要安装mime@^3版本的,mime@4开始使用的是ES Model,无法通过require引入
const mime = require("mime");

// 创建服务器
const server = http.createServer((req, res) => {
	 //解析请求地址
	 const url = new URL("http://localhost" + req.url);
	
	 // 获取匹配的路由;因为路由使用的是Server 的EventEmitter 实例注册的路由,
	 // 所以这里获取所有路由可以通过 server.eventNames()获取所有事件名称的方式,获取路由
	 // 复杂有业务场景时,可以自己实现路由模块
	 const routeInfo = server.eventNames().find((name) => name == url.pathname);
	
	 //如果匹配到路由,则触发对应的路由事件,反之全部按照静态文件处理
	 if (routeInfo) {
	   server.emit(`${url.pathname}`, req, res, url);
	 } else {
	 	// 触发静态资源路由事件
	   server.emit(`route:public`, req, res, url);
	 }
});

// 监听8080端口,也可以通过传入0 获取随机端口,并通过,server.address()获取端口信息
server.listen("8080", () => {
  console.log("Servre  Running",server.address());
});

/**
 * 静态资源
 */
server.on("route:public", (req, res, url) => {
  //格式化文件路径,如果路径结尾以 "/"结束,则加上index.html
  const filepath = url.pathname.endsWith("/")
    ? url.pathname + "index.html"
    : url.pathname;

  // 读取public文件夹下匹配的文件
  readFile(`./public${filepath}`, (error, data) => {
  	
  	//如果读取文件失败,则返回404
    if (error) {
      res.writeHead(404);
      res.end("");
    } else {
      //读取成功,返回200、文件MIME类型,这里使用的是mime插件
      res.writeHead(200, {
        "Content-Type": mime.getType(filepath),
      });
      // 返回文件流
      res.end(data);
    }
  });
});

/**
 * 普通请求
 */
server.on("/normal", (req, res, url) => {
  const id = url.searchParams.get("_id");

  res.writeHead(200, {
    "Content-Type": "application/json",
  });
  res.end(JSON.stringify({ id }));
});

/**
 * SSE 请求
 */
server.on("/sse", (req, res) => {
  // 先向客户端响应SSE响应头信息,让客户端知道接口是一个SSE接口,不要关闭连接
  res.writeHead(200, {
    "Access-Control-Allow-Origin": "*",
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    Connection: "keep-alive",
  });

  // 每隔3秒发送一个数据
  setInterval(() => {
    res.write("data:This is SSE API\n\n");
  }, 3000);
});

index.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <img src="./images/1.png" alt="" srcset="" />
    <script>
       
       fetch("/normal?_id=1111")
         .then((res) => res.json())
         .then((res) => {
           console.log("---client", res);
         });

	  // 请求,并监听sse接口
      var evtSource = new EventSource("/sse");
      evtSource.onmessage = function (e) {
        console.log("---sse", e.data);
      };
    </script>
  </body>
</html>

注意:

  • 如果不是最求很高的性能需求,推荐使用完善的express创建服务器,
  • http.Server 适合对NodeJs 进阶练习使用,可以开发者知道一个请求从入站到出站的整个流程
相关推荐
whinc5 分钟前
Node.js技术周刊 2026年第16周
前端·javascript
DyLatte8 分钟前
我做了个AI项目后才发现:会做事的人,正在输给会讲故事的人
前端·后端·程序员
深海鱼在掘金8 分钟前
从Claude Code泄露源码看工程架构:第三章 — CLI 启动链路的分流策略与按需加载机制
前端·人工智能·设计模式
踩着两条虫8 分钟前
VTJ:低代码平台原理
前端·低代码·ai编程
颜酱10 分钟前
提示词强化1:三个让大模型更「听话」的习惯
前端·javascript·人工智能
破茧成蝶81010 分钟前
修复播报缺失文字的bug,改为“播放单个 -> 等待结束 -> 延迟 10ms秒 -> 播放下一个”的递归/循环模式
前端
颜酱14 分钟前
提示词强化 2:元提示(Meta-Prompt)与动态提示词
前端·javascript·人工智能
handler0115 分钟前
Linux: 基本指令知识点(3)
linux·服务器·c语言·开发语言·c++·笔记
fengci.16 分钟前
ctfshow其他(web408-web432)
android·开发语言·前端·学习·php
向宇it18 分钟前
获取服务器hung住时的崩溃日志并自动系统重启——监听服务器异常崩溃问题
运维·服务器