관련 권장 사항: "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/v1npm run test
를 실행하여 testnpm run test
可以测试
当访问的路径是文件夹的时候程序会报错
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:9527
언제 경로가 폴더이면 프로그램에서 오류를 보고합니다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 중국어 웹사이트의 기타 관련 기사를 참조하세요!