64 # 实现一个 http-server

这篇具有很好参考价值的文章主要介绍了64 # 实现一个 http-server。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

准备工作

上一节实现了通过 commander 的配置获取到用户的参数,下面完成借用 promise 写成类的方法一节没有完成的任务,实现一个 http-server,https://www.npmjs.com/package/http-server,http-server 是一个简单的零配置命令行静态 HTTP 服务器。

需要用到的核心模块

const http = require("http");
const path = require("path");
const url = require("url");
const fs = require("fs").promises;
const { createReadStream, createWriteStream, readFileSync } = require("fs");

需要用到的第三方模块:

  • ejs 用来进行模板渲染
  • mime 用来根据文件扩展名获取 MIME type, 也可以根据 MIME type 获取扩展名。
  • chalk 用来控制台输出着色
  • debug 可以根据环境变量来进行打印
const ejs = require("ejs"); // 服务端读取目录进行渲染
const mime = require("mime");
const chalk = require("chalk");
const debug = require("debug")("server");

安装依赖

npm install ejs@3.1.3 debug@4.1.1 mime@2.4.6 chalk@4.1.0

64 # 实现一个 http-server,Node / Node 框架,前端工程架构,http-server

配置环境变量

const debug = require("debug")("server");
// 根据环境变量来进行打印 process.env.EDBUG
debug("hello kaimo-http-server");
set DEBUG=server
kaimo-http-server

64 # 实现一个 http-server,Node / Node 框架,前端工程架构,http-server

代码实现

  1. 将拿到的配置数据开启一个 server

www.js 里面实现

#! /usr/bin/env node

const program = require("commander");
const { version } = require("../package.json");
const config = require("./config.js");
const Server = require("../src/server.js");

program.name("kaimo-http-server");
program.usage("[args]");
program.version(version);

Object.values(config).forEach((val) => {
    if (val.option) {
        program.option(val.option, val.description);
    }
});

program.on("--help", () => {
    console.log("\r\nExamples:");
    Object.values(config).forEach((val) => {
        if (val.usage) {
            console.log("  " + val.usage);
        }
    });
});

// 解析用户的参数
let parseObj = program.parse(process.argv);

let keys = Object.keys(config);

// 最终用户拿到的数据
let resultConfig = {};
keys.forEach((key) => {
    resultConfig[key] = parseObj[key] || config[key].default;
});

// 将拿到的配置数据开启一个 server
console.log("resultConfig---->", resultConfig);
let server = new Server(resultConfig);
server.start();
  1. 实现 server.js,主要的逻辑就是通过核心模块以及第三方模块将用户输入的参数,实现一个 Server 类,里面通过 start 方法开启服务,核心逻辑实现通过路径找到这个文件返回,如果是文件夹处理是否有 index.html 文件,没有的话就通过模板渲染文件夹里目录信息。
// 核心模块
const http = require("http");
const path = require("path");
const url = require("url");
const fs = require("fs").promises;
const { createReadStream, createWriteStream, readFileSync } = require("fs");

// 第三方模块
const ejs = require("ejs"); // 服务端读取目录进行渲染
const mime = require("mime");
const chalk = require("chalk");
const debug = require("debug")("server");
// 根据环境变量来进行打印 process.env.EDBUG
debug("hello kaimo-http-server");

// 同步读取模板
const template = readFileSync(path.resolve(__dirname, "template.ejs"), "utf-8");

class Server {
    constructor(config) {
        this.host = config.host;
        this.port = config.port;
        this.directory = config.directory;
        this.template = template;
    }
    async handleRequest(req, res) {
        let { pathname } = url.parse(req.url);
        // 需要对 pathname 进行一次转义,避免访问中文名称文件找不到问题
        console.log(pathname);
        pathname = decodeURIComponent(pathname);
        console.log(pathname);
        // 通过路径找到这个文件返回
        let filePath = path.join(this.directory, pathname);
        console.log(filePath);
        try {
            // 用流读取文件
            let statObj = await fs.stat(filePath);
            // 判断是否是文件
            if (statObj.isFile()) {
                this.sendFile(req, res, filePath, statObj);
            } else {
                // 文件夹的话就先尝试找找 index.html
                let concatFilePath = path.join(filePath, "index.html");
                try {
                    let statObj = await fs.stat(concatFilePath);
                    this.sendFile(req, res, concatFilePath, statObj);
                } catch (e) {
                    // index.html 不存在就列出目录
                    this.showList(req, res, filePath, statObj, pathname);
                }
            }
        } catch (e) {
            this.sendError(req, res, e);
        }
    }
    // 列出目录
    async showList(req, res, filePath, statObj, pathname) {
        // 读取目录包含的信息
        let dirs = await fs.readdir(filePath);
        console.log(dirs, "-------------dirs----------");
        try {
            let parseObj = dirs.map((item) => ({
                dir: item,
                href: path.join(pathname, item) // url路径拼接自己的路径
            }));
            // 渲染列表:这里采用异步渲染
            let templateStr = await ejs.render(this.template, { dirs: parseObj }, { async: true });
            console.log(templateStr, "-------------templateStr----------");
            res.setHeader("Content-type", "text/html;charset=utf-8");
            res.end(templateStr);
        } catch (e) {
            this.sendError(req, res, e);
        }
    }
    // 读取文件返回
    sendFile(req, res, filePath, statObj) {
        // 设置类型
        res.setHeader("Content-type", mime.getType(filePath) + ";charset=utf-8");
        // 读取文件进行响应
        createReadStream(filePath).pipe(res);
    }
    // 专门处理错误信息
    sendError(req, res, e) {
        debug(e);
        res.statusCode = 404;
        res.end("Not Found");
    }
    start() {
        const server = http.createServer(this.handleRequest.bind(this));
        server.listen(this.port, this.host, () => {
            console.log(chalk.yellow(`Starting up kaimo-http-server, serving ./${this.directory.split("\\").pop()}\r\n`));
            console.log(chalk.green(`       http://${this.host}:${this.port}`));
        });
    }
}

module.exports = Server;
  1. 模板 template.ejs 的代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>列表模板</title>
    </head>

    <body>
        <% dirs.forEach(item=> { %>
        <li>
            <a href="<%=item.href%>"><%=item.dir%></a>
        </li>
        <% }) %>
    </body>
</html>

实现效果

控制台我们输入下面命令启动一个端口为 4000 的服务

kaimo-http-server --port 4000

我们访问 http://localhost:4000/,可以看到

64 # 实现一个 http-server,Node / Node 框架,前端工程架构,http-server

我们在进入 public 文件,里面有 index.html 文件

64 # 实现一个 http-server,Node / Node 框架,前端工程架构,http-server

点击 public 目录进入 http://localhost:4000/public,可以看到返回了 index.html 页面

64 # 实现一个 http-server,Node / Node 框架,前端工程架构,http-server

我们在进入 public2 文件,里面没有 index.html 文件

64 # 实现一个 http-server,Node / Node 框架,前端工程架构,http-server

点击 public2 目录进入 http://localhost:4000/public2,看到的就是列表

64 # 实现一个 http-server,Node / Node 框架,前端工程架构,http-server

我们可以点击任何的文件查看:比如 凯小默.txt

64 # 实现一个 http-server,Node / Node 框架,前端工程架构,http-server文章来源地址https://www.toymoban.com/news/detail-635700.html

到了这里,关于64 # 实现一个 http-server的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 73 # 发布自己的 http-server 到 npm

    1、添加 .npmignore 文件,忽略不需要的文件 2、去官网https://www.npmjs.com/检查自己的包名是否被占用 3、切换到官方源,然后检查确认 4、登录 npm 账号 5、发布 6、查看发布情况,发布成功之后,等一会,我们就能看到自己的包在 npm 上了 7、更新版本,我们添加一个 README.md 文件

    2024年02月11日
    浏览(29)
  • 通过 http-server 运行刚打包出来的脚手架项目

    这里 我打包了自己的vue项目 react其实也一样 如果我直接 打开打包出来的 dist 下面的index.html 会出现白屏资源找不到 或者跨域等问题 这个问题其实配个nginx也能解决 但是其实如果只是想做个测试 nginx就太麻烦了 我们可以通过npm指令 全局安装一个http-server 终端执行 安装好依赖

    2024年02月09日
    浏览(28)
  • http-server使用,启动本地服务器 & 使用serve包本地启动

    http-server使用,启动本地服务器 使用serve包本地启动 直接打开html文件,跨域不渲染图片 1、简介 官网:https://github.com/http-party/http-server http-server是一个简单的零配置命令行 http服务器 。 它足够强大,足以用于生产用途,但它既简单又易于破解,可用于测试,本地开发和学习。

    2024年02月02日
    浏览(46)
  • 如何使用Node.js快速创建HTTP服务器并实现公网访问本地Server

    Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台运行环境。Node.js 由 OpenJS Foundation(原为 Node.js Foundation,已与 JS Foundation 合并)持有和维护,亦为 Linux 基金会的项目。Node.js 采用 Google 开发的 V8 运行代码,使用事件驱动、非阻塞和异步输入输出模型等技术来提高

    2024年01月15日
    浏览(44)
  • java基础 - 实现一个简单的Http接口功能自动化测试框架(HttpClient + TestNG)

    已知现在已经用Spring boot框架搭建了一个简单的web服务,并且有现成的Controller来处理http请求,以之前搭建的图书管理服务为例,BookController的源码如下: 在搭建一个Http接口功能自动化测试框架之前,我们需要思考几个问题: 1、http请求的发送,使用什么实现? 2、接口返回的

    2024年02月05日
    浏览(40)
  • window中安装Apache http server(httpd-2.4.58-win64-VS17)

    1、下载windows版本的的httpd, https://httpd.apache.org/docs/current/platform/windows.html#down 这里选择的是Apache Lounge编译的版本 https://www.apachelounge.com/download/ 2、解压到指定目录,这里解压到D盘根目录,得到D:Apache24 3、修改配置文件http.conf 4、修改之后,检测配置文件是否有语法错误 语法

    2024年01月20日
    浏览(48)
  • 前端使用node.js连接sql.server数据库教程

    最近项目中要用到node写接口然后连接公司现有的sql.server数据库,再把执行结果返回给前端(还是我),因为之前一直做前端这块,后端这方面不是很懂,花了很长的时间终于研究出来了(还是太菜了,走了很多弯路),所以写个博客,一是复习巩固,二是给其他有需要的小伙伴一个参考,尽量

    2024年02月11日
    浏览(44)
  • 前端项目部署自动检测更新后通知用户刷新页面(前端实现,技术框架vue、js、webpack)——方案一:编译项目时动态生成一个记录版本号的文件

    当我们重新部署前端项目的时候,如果用户一直停留在页面上并未刷新使用,会存在功能使用差异性的问题,因此,当前端部署项目后,需要提醒用户有去重新加载页面。 vue、js、webpack 编译项目时动态生成一个记录版本号的文件 轮询(20s、自己设定时间)这个文件,判断版

    2024年02月02日
    浏览(46)
  • json-server Node.js 服务,前端模拟后端提供json接口服务

    json-server Node.js 服务,前端模拟后端提供json接口服务 背景:    前后端分离的项目,如果前端写页面的话,必须的后端提供接口文件,作为前端等待时间太久,不便于开发进行,如果前端写的过程中自己搭建一个简要的后端的json服务接口,就是可以快速进行开发事项的进行,

    2024年02月16日
    浏览(30)
  • 使用node.js给前端发送一个图像验证码

    相信写过node的小伙伴都对此有相关了解 首先导入需要的包(//后有解释) const mysql = require(\\\"mysql\\\");   //用于创建和管理 MySQL 连接池。 const express = require(\\\"express\\\");//用于构建 Web 应用程序。 const app = express(); const interface = require(\\\"./interface\\\"); const bodyParser = require(\\\"body-parser\\\"); //用于

    2024年01月17日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包