【大前端】使用NodeJs HTTP模块创建web服务器、SSE通讯
Nodejs构建web服务器有很多中方式,常见的有两种:express
,http.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.htmlconst filepath = url.pathname.endsWith("/")? url.pathname + "index.html": url.pathname;// 读取public文件夹下匹配的文件readFile(`./public${filepath}`, (error, data) => {//如果读取文件失败,则返回404if (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 进阶练习使用,可以开发者知道一个请求从入站到出站的整个流程