node静态服务器实现静态读取文件或文件夹


Posted in Javascript onDecember 03, 2019

现在我们已经大致了解了node 的基本工作原理,现在来实现一个系统的功能 读取文件或者文件夹

采坑记录

中文输出乱码问题

res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('啊啊和嘎哈啊')

输出中出现中文乱码 附解决方案 ~

res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' })

res.writeHead(200, { 'Context-Type': 'text/plain' })
res.write('<head><meta charset="utf-8"/></head>')

文件读取方式

node 允许通过两种方式读取并输出文件

one : 以文件流的形式读取与返回一起进行,快 = 推荐

fs.createReadStream(filePath).pipe(res)

two : 先将文件整个读取,然后将文件内容一起返回,简单说这就是api的蹩脚使用 = 慢

fs.readFile(filePath, (err, data) => {
  if (err) return
  res.end(data)
})

读取文件或者文件夹

废话不说,上代码

require('./config/defaultConfig') 更新为以下

module.exports = {
   // 主机名称
   hostname: '127.0.0.1',
   // 端口号
   port: 6969,
   // 当前文件夹
   root: process.cwd()
  }
// 引入http内置模块
  const http = require('http')
  
  // 引入chalk 用于美化后台打印
  const chalk = require('chalk')
  
  const path = require('path')
  const fs = require('fs')
  // 引入基本配置
  const conf = require('./config/defaultConfig')
  
  // 创建一个server 实例
  const server = http.createServer((rep, res) => {
   // 拿到路径
   const filePath = path.join(conf.root, rep.url)
  
   // 判断是否为文件或者文件夹
   fs.stat(filePath, (err, stats) => {
    // 设置公共头部信息
    res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' })
    if (err) {
     // 状态码
     res.statusCode = 404
  
     // 找不到提示文本
     res.end(`${filePath} is 404`)
  
     return
    }
    if (stats.isFile()) {
     // 如果是文件 返回文件内容
     res.statusCode = 200
  
     fs.createReadStream(filePath).pipe(res)
    } else if (stats.isDirectory()) {
     // 如果是文件夹,返回文件列表
     fs.readdir(filePath, (err, files) => {
      if (err) return
      res.statusCode = 200
  
      res.end(files.join(','))
     })
    }
   })
  })
  
  // 监听 server 实例
  
  server.listen(conf.port, conf.hostname, () => {
   const addr = `http:// ${conf.hostname}:${conf.port}`
  
   console.info(`server startd at ${chalk.green(addr)}`)
  })

代码优化

上述代码存在很多回调,代码臃肿可读性差。下面利用异步将回调去除,达到优化效果

require-atomic-updates 注意eslint对于此项的限制, 为此将实参await 

const fs = require('fs')

const promisify = require('util').promisify
const stat = promisify(fs.stat)
const readdir = promisify(fs.readdir)

module.exports = async function(rep, res, filePath) {
 // 规避此问题require-atomic-updates报告在异步函数中重新分配变量时可能发生的竞争条件错误
 const awaitRes = await res
 awaitRes.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' })
 try {
  const stats = await stat(filePath)
  if (stats.isFile()) {
   // 如果是文件 返回文件内容
   awaitRes.statusCode = 200

   fs.createReadStream(filePath).pipe(awaitRes)
  } else if (stats.isDirectory()) {
   // 如果是文件夹,返回文件列表
   const file = readdir(filePath)
   awaitRes.statusCode = 200

   awaitRes.end(file.join(','))
  }
 } catch (ex) {
  // 状态码
  awaitRes.statusCode = 404

  // 找不到提示文本
  awaitRes.end(`${filePath} is 404`)
 }
}

app.js文件变更为

// 引入http内置模块
const http = require('http')

// 引入chalk 用于美化后台打印
const chalk = require('chalk')

const path = require('path')

const route = require('./header/route')
// 引入基本配置
const conf = require('./config/defaultConfig')

// 创建一个server 实例
const server = http.createServer((rep, res) => {
 // 拿到路径
 const filePath = path.join(conf.root, rep.url)
 route(rep, res, filePath)
})

// 监听 server 实例

server.listen(conf.port, conf.hostname, () => {
 const addr = `http:// ${conf.hostname}:${conf.port}`

 console.info(`server startd at ${chalk.green(addr)}`)
})

至此实现了通过hash路径输入,实现文件或文件夹的读取/前进后退

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Highslide.js是一款基于js实现的网页中图片展示插件
Mar 30 Javascript
javascript学习笔记(九) js对象 设计模式
Jun 19 Javascript
使用POST方式弹出窗口的两种方法示例介绍
Jan 29 Javascript
ZeroClipboard插件实现多浏览器复制功能(支持firefox、chrome、ie6)
Aug 30 Javascript
自己编写的支持Ajax验证的JS表单验证插件
May 15 Javascript
javascript数组去重的六种方法汇总
Aug 16 Javascript
XML、HTML、CSS与JS的区别整理
Feb 18 Javascript
浅谈javascript基础之客户端事件驱动
Jun 10 Javascript
原生js实现瀑布流布局
Mar 08 Javascript
基于vue-cli配置lib-flexible + rem实现移动端自适应
Dec 26 Javascript
在vue中使用setInterval的方法示例
Apr 16 Javascript
Vue的编码技巧与规范使用详解
Aug 28 Javascript
js实现时分秒倒计时
Dec 03 #Javascript
Vue实现验证码功能
Dec 03 #Javascript
JS实现压缩上传图片base64长度功能
Dec 03 #Javascript
js实现AI五子棋人机大战
May 28 #Javascript
angular inputNumber指令输入框只能输入数字的实现
Dec 03 #Javascript
JavaScript的console命令使用实例
Dec 03 #Javascript
JavaScript实现京东放大镜效果
Dec 03 #Javascript
You might like
Linux下php5.4启动脚本
2014/08/03 PHP
自定义session存储机制避免会话保持问题
2014/10/08 PHP
jquery键盘事件使用介绍
2011/11/01 Javascript
让元素在网页中可拖动示例代码
2013/08/13 Javascript
javascript实现的一个带下拉框功能的文本框
2014/05/08 Javascript
JavaScript编程学习技巧汇总
2016/02/21 Javascript
浅谈JavaScript中小数和大整数的精度丢失
2016/05/31 Javascript
bootstrap fileinput 上传插件的基础使用
2017/02/17 Javascript
weex slider实现滑动底部导航功能
2017/08/28 Javascript
jQuery中$原理实例分析
2018/08/13 jQuery
webpack4.x CommonJS模块化浅析
2018/11/09 Javascript
解决Vue-Router升级导致的Uncaught (in promise)问题
2020/08/07 Javascript
Vue实现省市区三级联动
2020/12/27 Vue.js
[45:10]NB vs Liquid Supermajor小组赛 A组胜者组决赛 BO3 第二场 6.2
2018/06/04 DOTA
[43:41]VP vs RNG 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
[42:24]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第三场 11.27
2020/12/01 DOTA
在漏洞利用Python代码真的很爽
2007/08/26 Python
python实现目录树生成示例
2014/03/28 Python
Python深入学习之装饰器
2014/08/31 Python
Python中list列表的一些进阶使用方法介绍
2015/08/15 Python
python针对excel的操作技巧
2018/03/13 Python
Python多继承原理与用法示例
2018/08/23 Python
实例详解Python模块decimal
2019/06/26 Python
TALLY WEiJL法国网上商店:服装、时装及配饰
2019/08/31 全球购物
伦敦最受欢迎的蛋糕店:Konditor & Cook
2019/11/01 全球购物
会计应届生的自荐信
2013/12/13 职场文书
《最可爱的人》教学反思
2014/02/14 职场文书
对祖国的寄语大全
2014/04/11 职场文书
党建工作经验交流材料
2014/05/25 职场文书
课前一分钟演讲稿
2014/08/26 职场文书
关于九一八事变的演讲稿2014
2014/09/17 职场文书
2015年反洗钱工作总结
2015/04/25 职场文书
新学期开学标语2015
2015/07/16 职场文书
八年级地理课件资料及考点知识分享
2019/08/30 职场文书
springboot拦截器无法注入redisTemplate的解决方法
2021/06/27 Java/Android
数据分析数据库ClickHouse在大数据领域应用实践
2022/04/03 MySQL