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

发布于:2025-05-24 ⋅ 阅读:(21) ⋅ 点赞:(0)

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

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

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

目录结构

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

index.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

<!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 进阶练习使用,可以开发者知道一个请求从入站到出站的整个流程

网站公告

今日签到

点亮在社区的每一天
去签到