【大前端】使用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 进阶练习使用,可以开发者知道一个请求从入站到出站的整个流程
相关推荐
李白你好1 分钟前
Linux 本地提权工具支持Linux 内核和 Polkit 漏洞
linux·运维·服务器
陳10302 分钟前
Linux:System V IPC
linux·运维·服务器
vivo互联网技术9 分钟前
VAPD AgentKit:可组合 Agent 前端通用库实践
前端·ai·架构·agent
lichenyang45313 分钟前
鸿蒙聊天 Demo 练习 02:AI 回复打字机输出与 ForEach 刷新问题
前端
键盘上的GG小怪兽GG16 分钟前
Debian 安装CUPS操作
linux·服务器·debian
Hello--_--World17 分钟前
利用CDN进行首屏优化。能不能看CDN与本地服务器谁快用谁?
运维·服务器·前端·javascript·vite
猫不易25 分钟前
在 Warp + tmux 下使用 Claude Code:一次剪贴板踩坑记录
前端
sa1002725 分钟前
京东评论 API 实战:JSON 数据结构、字段含义与解析技巧
前端·数据结构·json
snow@li27 分钟前
前端:MVP 深度全解 / 从核心理念到实战落地
前端
vennnnnnnnnnnnnn29 分钟前
Excel 导入原文保留与内联排名配置问题复盘
前端·数据库·excel