亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于 Node 實(shí)現(xiàn)簡(jiǎn)易 serve靜態(tài)資源服務(wù)器的示例詳解

 更新時(shí)間:2022年06月20日 15:39:50   作者:三天不喝水  
靜態(tài)資源服務(wù)器(HTTP 服務(wù)器)可以將靜態(tài)文件(如 js、css、圖片)等通過(guò) HTTP 協(xié)議展現(xiàn)給客戶端。本文介紹如何基于 Node 實(shí)現(xiàn)一個(gè)簡(jiǎn)易的靜態(tài)資源服務(wù)器,感興趣的朋友一起看看吧

前言

靜態(tài)資源服務(wù)器(HTTP 服務(wù)器)可以將靜態(tài)文件(如 js、css、圖片)等通過(guò) HTTP 協(xié)議展現(xiàn)給客戶端。本文介紹如何基于 Node 實(shí)現(xiàn)一個(gè)簡(jiǎn)易的靜態(tài)資源服務(wù)器(類似于 serve)。

基礎(chǔ)示例

const fs = require("node:fs");
const fsp = require("node:fs/promises");
const http = require("node:http");

const server = http.createServer(async (req, res) => {
  const stat = await fsp.stat("./index.html");
  res.setHeader("content-length", stat.size);
  fs.createReadStream("./index.html").pipe(res);
});

server.listen(3000, () => {
  console.log("Listening 3000...");
});

在上述示例中,我們創(chuàng)建了一個(gè) http server,并以 stream 的方式返回一個(gè) index.html 文件。其中,分別引入引入了 Node 中的 fs、fsp、http 模塊,各個(gè)模塊的作用如下:

  • fs: 文件系統(tǒng)模塊,用于文件讀寫。
  • fsp: 使用 promise 形式的文件系統(tǒng)模塊。
  • http: 用于搭建 HTTP 服務(wù)器。

簡(jiǎn)易 serve 實(shí)現(xiàn)

serve 的核心功能非常簡(jiǎn)單,它以命令行形式指定服務(wù)的文件根路徑和服務(wù)端口,并創(chuàng)建一個(gè) http 服務(wù)。

arg - 命令行參數(shù)讀取

使用 npm 包 arg 讀取命令行參數(shù),www.npmjs.com/package/arg。

chalk - 控制臺(tái)信息輸出

使用 npm 包 chalk 在控制臺(tái)輸出帶有顏色的文字信息,方便調(diào)試預(yù)覽。

源碼

// Native - Node built-in module
const fs = require("node:fs");
const fsp = require("node:fs/promises");
const http = require("node:http");
const path = require("node:path");

// Packages
const arg = require("arg");
const chalk = require("chalk");

var config = {
  entry: "",
  rewrites: [],
  redirects: [],
  etag: false,
  cleanUrls: false,
  trailingSlash: false,
  symlink: false,
};

/**
 * eg: --port <string> or --port=<string>
 * node advance.js -p 3000 | node advance.js --port 3000
 */
const args = arg({
  "--port": Number,
  "--entry": String,
  "--rewrite": Boolean,
  "--redirect": Boolean,
  "--etag": Boolean,
  "--cleanUrls": Boolean,
  "--trailingSlash": Boolean,
  "--symlink": Boolean,
});

const resourceNotFound = (response, absolutePath) => {
  response.statusCode = 404;
  fs.createReadStream(path.join("./html", "404.html")).pipe(response);
};

const processDirectory = async (absolutePath) => {
  const newAbsolutePath = path.join(absolutePath, "index.html");

  try {
    const newStat = await fsp.lstat(newAbsolutePath);
    return [newStat, newAbsolutePath];
  } catch (e) {
    return [null, newAbsolutePath];
  }
};

/**
 * @param { http.IncomingMessage } req
 * @param { http.ServerResponse } res
 * @param { config } config
 */
const handler = async (request, response, config) => {
  // 從 request 中獲取 pathname
  const pathname = new URL(request.url, `http://${request.headers.host}`)
    .pathname;

  // 獲取絕對(duì)路徑
  let absolutePath = path.resolve(
    config["--entry"] || "",
    path.join(".", pathname)
  );

  let statusCode = 200;
  let fileStat = null;

  // 獲取文件狀態(tài)
  try {
    fileStat = await fsp.lstat(absolutePath);
  } catch (e) {
    // console.log(chalk.red(e));
  }

  if (fileStat?.isDirectory()) {
    [fileStat, absolutePath] = await processDirectory(absolutePath);
  }

  if (fileStat === null) {
    return resourceNotFound(response, absolutePath);
  }

  let headers = {
    "Content-Length": fileStat.size,
  };

  response.writeHead(statusCode, headers);

  fs.createReadStream(absolutePath).pipe(response);
};

const startEndpoint = (port, config) => {
  const server = http.createServer((request, response) => {
    // console.log("request: ", request);
    handler(request, response, config);
  });

  server.on("error", (err) => {
    const { code, port } = err;
    if (code === "EADDRINUSE") {
      console.log(chalk.red(`address already in use [:::${port}]`));
      console.log(chalk.green(`Restart server on [:::${port + 1}]`));
      startEndpoint(port + 1, entry);
      return;
    }
    process.exit(1);
  });

  server.listen(port, () => {
    console.log(chalk.green(`Open http://localhost:${port}`));
  });
};

startEndpoint(args["--port"] || 3000, args);

擴(kuò)展

rewrite 和 redirect 的區(qū)別?

  • rewrite: 重寫,是指服務(wù)器在接收到客戶端的請(qǐng)求后,返回的是別的文件內(nèi)容。舉個(gè)例子,瀏覽器 A 向服務(wù)器請(qǐng)求了一個(gè)資源 indexA.html,服務(wù)器接收到 indexA.html 請(qǐng)求后,拿 indexB.html 作為實(shí)際的響應(yīng)內(nèi)容返回給瀏覽器 A,整個(gè)過(guò)程對(duì)于 A 來(lái)說(shuō)是無(wú)感知的。
  • redirect: 重定向,瀏覽器 A 向服務(wù)器請(qǐng)求一個(gè) index.html,服務(wù)器告訴瀏覽器 A “資源不在當(dāng)前請(qǐng)求路徑,需要去通過(guò)另外一個(gè)地址請(qǐng)求”。瀏覽器接收到新地址后,重新請(qǐng)求。整個(gè)過(guò)程中,瀏覽器需要請(qǐng)求兩次。

到此這篇關(guān)于基于 Node 實(shí)現(xiàn)簡(jiǎn)易 serve(靜態(tài)資源服務(wù)器)的文章就介紹到這了,更多相關(guān)node實(shí)現(xiàn)靜態(tài)資源服務(wù)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解nodejs通過(guò)代理(proxy)發(fā)送http請(qǐng)求(request)

    詳解nodejs通過(guò)代理(proxy)發(fā)送http請(qǐng)求(request)

    本篇文章主要介紹了nodejs通過(guò)代理(proxy)發(fā)送http請(qǐng)求(request),具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-09-09
  • nodejs+socket.io實(shí)現(xiàn)p2p消息實(shí)時(shí)發(fā)送的項(xiàng)目實(shí)踐

    nodejs+socket.io實(shí)現(xiàn)p2p消息實(shí)時(shí)發(fā)送的項(xiàng)目實(shí)踐

    本文主要介紹了nodejs+socket.io實(shí)現(xiàn)p2p消息實(shí)時(shí)發(fā)送,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Node.js中的模塊系統(tǒng)介紹

    Node.js中的模塊系統(tǒng)介紹

    這篇文章介紹了Node.js中的模塊系統(tǒng),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 淺談Node.js中的定時(shí)器

    淺談Node.js中的定時(shí)器

    本文給大家分享的是Node.js中的定時(shí)器的相關(guān)資料,十分的全面細(xì)致,有需要的小伙伴可以參考下。
    2015-06-06
  • Node.js Koa2使用JWT進(jìn)行鑒權(quán)的方法示例

    Node.js Koa2使用JWT進(jìn)行鑒權(quán)的方法示例

    這篇文章主要介紹了Node.js Koa2使用JWT進(jìn)行鑒權(quán)的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 利用Node.JS實(shí)現(xiàn)郵件發(fā)送功能

    利用Node.JS實(shí)現(xiàn)郵件發(fā)送功能

    其實(shí)利用Node.JS實(shí)現(xiàn)郵件發(fā)送這個(gè)功能很多人都寫過(guò)了,但是網(wǎng)上有的代碼不能用,版本較老,所以想著寫下自己摸索的方法來(lái)實(shí)現(xiàn)。現(xiàn)在分享給大家,感興趣的朋友們可以一起學(xué)習(xí)學(xué)習(xí)。
    2016-10-10
  • 前端Electron新手入門教程詳解

    前端Electron新手入門教程詳解

    這篇文章主要介紹了Electron新手入門教程詳解,首先圍繞Electron框架的關(guān)鍵知識(shí)點(diǎn)進(jìn)行詳細(xì)講解,然后對(duì)DEMO程序進(jìn)行分析,讓前端開發(fā)人員對(duì)使用Electron開發(fā)桌面應(yīng)用程序有一個(gè)初步的了解。,需要的朋友可以參考下
    2019-06-06
  • Node.js?與并發(fā)模型的詳細(xì)介紹

    Node.js?與并發(fā)模型的詳細(xì)介紹

    這篇文章主要介紹了Node.js?與并發(fā)模型的詳細(xì)介紹,Node.js?現(xiàn)在已成為構(gòu)建高并發(fā)網(wǎng)絡(luò)應(yīng)用服務(wù)工具箱中的一員,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,需要的朋友可以參考一下
    2022-07-07
  • 使用pm2運(yùn)行node應(yīng)用的流程步驟

    使用pm2運(yùn)行node應(yīng)用的流程步驟

    PM2是一個(gè)功能強(qiáng)大的進(jìn)程管理工具,專為?Node.js?應(yīng)用設(shè)計(jì),它提供了進(jìn)程管理、日志管理、負(fù)載均衡和性能監(jiān)控等功能,幫助開發(fā)者輕松應(yīng)對(duì)生產(chǎn)環(huán)境中的各種挑戰(zhàn),本文給大家介紹了使用pm2?運(yùn)行node應(yīng)用的流程步驟,需要的朋友可以參考下
    2024-03-03
  • Koa2微信公眾號(hào)開發(fā)之消息管理

    Koa2微信公眾號(hào)開發(fā)之消息管理

    這篇文章主要介紹了Koa2微信公眾號(hào)開發(fā)之消息管理,這一節(jié)我們就來(lái)看看公眾號(hào)的消息管理。并實(shí)現(xiàn)一個(gè)自動(dòng)回復(fù)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05

最新評(píng)論