【大前端】使用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 进阶练习使用,可以开发者知道一个请求从入站到出站的整个流程
相关推荐
海盐泡泡龟2 小时前
web常见的攻击方式有哪些?如何防御?
前端·vue.js·webpack
EndingCoder3 小时前
React从基础入门到高级实战:React 基础入门 - React Hooks 入门
前端·javascript·react.js·前端框架
EndingCoder3 小时前
React从基础入门到高级实战:React 基础入门 - JSX与组件基础
前端·javascript·react.js·前端框架
天氰色等烟雨4 小时前
HTTP Digest 认证:原理剖析与服务端实现详解
网络·网络协议·http
Quke陆吾4 小时前
Vue框架1(vue搭建方式1,vue指令,vue实例生命周期)
前端·javascript·vue.js
zym大哥大5 小时前
网络层IP协议
linux·服务器·网络
五花肉村长5 小时前
Linux-读者写著问题和读写锁
linux·运维·服务器·开发语言·数据库·visualstudio
Oscar_02085 小时前
uniapp+ts 多环境编译
前端·vue.js·typescript·uni-app
凯雀安全5 小时前
在kali中搞个jdk1.8.,又不破坏环境
linux·运维·服务器