Home  >  Article  >  Web Front-end  >  Node.js learning static resource server

Node.js learning static resource server

青灯夜游
青灯夜游forward
2020-12-14 18:20:072826browse

Node.js learning static resource server

Related recommendations: "nodejs Tutorial"

implements the simplest static resource server when creating an HTTP server, and can write code Transform, add folder preview function, expose some configurations, and turn it into a customizable static resource server module

Modularization

The ideal way to use a customizable static resource server It should be like this

const StaticServer = require('YOUR_STATIC_SERVER_FILE_PATH');

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

staticServer.start();

staticServer.close();

This way of use requires the code to be modularized. It is very simple to implement a module in 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;

Full code: https://github.com/Samaritan89/ static-server/tree/v1
Executenpm run test Can test
Node.js learning static resource server
Node.js learning static resource server

Support folder preview

When the access path is a folder, the program will report an error

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'
}

Because fs.createReadStream tries to read the folder, it needs compatibility to return a directory page when the access path is a folder, that is Determine the file type after 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);
    }
  }
});

Traversing to generate html requires the knowledge introduced in the folder operation chapter. In order to facilitate the generation of HTML, the demo uses the Handlebar template engine, the main logic

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);
}

You can clearly see this change through the git code modification record: https://github.com/Samaritan89/static-server/commit/5565788dc317f29372f6e67e6fd55ec92323d0ea

Also executed in the project root directory npm run test, use the browser to visit 127.0.0.1:9527 You can see the display of the directory file
Node.js learning static resource server
Full code: https://github. com/Samaritan89/static-server/tree/v2

For more programming-related knowledge, please visit: Programming Teaching! !

The above is the detailed content of Node.js learning static resource server. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete