Node.js 학습 정적 리소스 서버

青灯夜游
풀어 주다: 2020-12-14 18:20:07
앞으로
2826명이 탐색했습니다.

Node.js 학습 정적 리소스 서버

관련 권장 사항: "nodejs Tutorial"

은 HTTP 서버를 생성할 때 가장 간단한 정적 리소스 서버를 구현하고, 폴더 미리 보기 기능을 추가하고, 일부 구성을 노출하고, 이를 사용자 정의 가능한 정적 리소스 서버 모듈

모듈화

사용자 정의 가능한 정적 리소스 서버를 사용하는 이상적인 방법은 다음과 같습니다

const StaticServer = require('YOUR_STATIC_SERVER_FILE_PATH');

const staticServer = new StaticServer({
	port: 9527,
  root: '/public',
});

staticServer.start();

staticServer.close();
로그인 후 복사

이 사용 방법에는 코드를 모듈화해야 합니다. Node.js에서 모듈을 구현하는 것은 매우 간단합니다. Node.js

const http = require('http');
const fs = require('fs');
const path = require('path');
const mime = require('mime-types');

const defaultConf = require('./config');

class StaticServer {
  constructor(options = {}) {
    this.config = Object.assign(defaultConf, options);
  }

  start() {
    const { port, root } = this.config;

    this.server = http.createServer((req, res) => {
      const { url, method } = req;

      if (method !== 'GET') {
        res.writeHead(404, {
          'content-type': 'text/html',
        });
        res.end('请使用 GET 方法访问文件!');
        return false;
      }

      const filePath = path.join(root, url);
      fs.access(filePath, fs.constants.R_OK, err => {
        if (err) {
          res.writeHead(404, {
            'content-type': 'text/html',
          });
          res.end('文件不存在!');

        } else {
          res.writeHead(200, {
            'content-type': mime.contentType(path.extname(url)),
          });
          fs.createReadStream(filePath).pipe(res);
        }
      });
    }).listen(port, () => {
      console.log(`Static server started at port ${port}`);
    });
  }

  stop() {
    this.server.close(() => {
      console.log(`Static server closed.`);
    });
  }
}

module.exports = StaticServer;
로그인 후 복사

전체 코드: https://github.com/Samaritan89/static-server/tree/v1
npm run test를 실행하여 testnpm run test 可以测试
Node.js 학습 정적 리소스 서버
Node.js 학습 정적 리소스 서버

支持文件夹预览

当访问的路径是文件夹的时候程序会报错

Error: EISDIR: illegal operation on a directory, read
Emitted 'error' event on ReadStream instance at:
    at internal/fs/streams.js:217:14
    at FSReqCallback.wrapper [as oncomplete] (fs.js:524:5) {
  errno: -21,
  code: 'EISDIR',
  syscall: 'read'
}
로그인 후 복사

因为 fs.createReadStream 尝试读取文件夹,需要兼容下访问路径是文件夹的时候,返回一个目录页,也就是在 fs.access 之后判断文件类型

fs.access(filePath, fs.constants.R_OK, err => {
  if (err) {
    res.writeHead(404, {
      'content-type': 'text/html',
    });
    res.end('文件不存在!');

  } else {
    const stats = fs.statSync(filePath);
    const list = [];
    if (stats.isDirectory()) {
      // 如果是文件夹则遍历文件夹,生成改文件夹内的文件树
      // 遍历文件内容,生成 html

    } else {
      res.writeHead(200, {
        'content-type': mime.contentType(path.extname(url)),
      });
      fs.createReadStream(filePath).pipe(res);
    }
  }
});
로그인 후 복사

遍历生成 html 部分需要用到 文件夹操作 章节介绍的知识,为了方便生成 HTML,demo 使用了 Handlebar 模板引擎,主要逻辑

if (stats.isDirectory()) {
  // 如果是文件夹则遍历文件夹,生成改文件夹内的文件树
  const dir = fs.opendirSync(filePath);
  let dirent = dir.readSync();
  while (dirent) {
    list.push({
      name: dirent.name,
      path: path.join(url, dirent.name),
      type: dirent.isDirectory() ? 'folder' : 'file',
    });
    dirent = dir.readSync();
  }
  dir.close();

  res.writeHead(200, {
    'content-type': 'text/html',
  });

  // 对文件顺序重排,文件夹在文件前面,相同类型按字母排序,不区分大小写
  list.sort((x, y) => {
    if (x.type > y.type) {
      // 'folder' > 'file', 返回 -1,folder 在 file 之前
      return -1;
    } else if (x.type == y.type) {
      return compare(x.name.toLowerCase(), y.name.toLowerCase());
    } else {
      return 1;
    }
  });

  // 使用 handlebars 模板引擎,生成目录页面 html
  const html = template({ list });
  res.end(html);
}
로그인 후 복사

通过 git 代码修改记录可以清晰看到本次的变更:https://github.com/Samaritan89/static-server/commit/5565788dc317f29372f6e67e6fd55ec92323d0ea

同样在项目根目录执行 npm run test ,使用浏览器访问 127.0.0.1:9527Node.js 학습 정적 리소스 서버
Node.js 학습 정적 리소스 서버Node.js 학습 정적 리소스 서버

접속 시 지원 폴더 미리보기

언제 경로가 폴더이면 프로그램에서 오류를 보고합니다rrreeefs.createReadStream이 폴더를 읽으려고 하기 때문에 액세스 경로가 폴더이고 디렉터리 페이지를 반환할 때 호환성이 필요합니다. 즉 파일 형식은 다음에 결정됩니다. fs.access

rrreee
🎜HTML을 생성하려면 폴더 작업 장에서 소개한 지식이 필요합니다. HTML 생성을 용이하게 하기 위해 데모에서는 핸들바 템플릿 엔진을 사용합니다🎜
rrreee. 🎜git 코드 수정 기록을 통해 명확하게 확인할 수 있습니다. 이 변경 사항: https://github.com/Samaritan89/static-server/commit/5565788dc317f29372f6e67e6fd55ec92323d0ea🎜🎜 또한 프로젝트 루트 디렉터리에서 npm run test를 실행하세요. , 브라우저를 사용하여 127.0.0.1:9527에 액세스하면 디렉터리 파일의 표시를 볼 수 있습니다 🎜🎜🎜전체 코드: https://github.com/Samaritan89/static-server/tree/v2 🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 교육 🎜을 방문하세요! ! 🎜

위 내용은 Node.js 학습 정적 리소스 서버의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:segmentfault.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿