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
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
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
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!