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 相关文章推荐
JavaScript网页制作特殊效果用随机数
May 22 Javascript
js 表单验证方法(实用)
Apr 28 Javascript
js parsefloat parseint 转换函数
Jan 21 Javascript
actionscript与javascript的区别
May 25 Javascript
javascript中if和switch,==和===详解
Jul 30 Javascript
angularjs 表单密码验证自定义指令实现代码
Oct 27 Javascript
JS中对数组元素进行增删改移的方法总结
Dec 15 Javascript
js返回顶部实例分享
Dec 21 Javascript
微信小程序通过api接口将json数据展现到小程序示例
Jan 20 Javascript
jQuery点击头像上传并预览图片
Feb 23 Javascript
vue数据双向绑定原理解析(get &amp; set)
Mar 08 Javascript
ant design实现圈选功能
Dec 17 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
php 设计模式之 工厂模式
2008/12/19 PHP
PHP中使用虚代理实现延迟加载技术
2014/11/05 PHP
jQuery 源代码显示控件 (Ajax加载方式).
2009/05/18 Javascript
单独使用CKFinder选择图片的方法
2010/08/21 Javascript
利用jquery包将字符串生成二维码图片
2013/09/12 Javascript
jquery如何获取复选框的值
2013/12/12 Javascript
input:checkbox多选框实现单选效果跟radio一样
2014/06/16 Javascript
JavaScript如何禁止Backspace键
2015/12/02 Javascript
js实现的彩色方块飞舞奇幻效果
2016/01/27 Javascript
理解javascript中Map代替循环
2016/02/26 Javascript
javascript实现平滑无缝滚动
2020/08/09 Javascript
基于Bootstrap的Metronic框架实现页面链接收藏夹功能
2016/08/29 Javascript
微信小程序 传值取值的几种方法总结
2017/01/16 Javascript
Javascript继承机制详解
2017/05/30 Javascript
npm的lock机制解析
2019/06/20 Javascript
JS 自执行函数原理及用法
2019/08/05 Javascript
js实现贪吃蛇小游戏
2019/10/29 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
2020/09/28 Javascript
Python代码的打包与发布详解
2014/07/30 Python
Python是编译运行的验证方法
2015/01/30 Python
Python中使用urllib2模块编写爬虫的简单上手示例
2016/01/20 Python
python基础while循环及if判断的实例讲解
2017/08/25 Python
Python中使用Counter进行字典创建以及key数量统计的方法
2018/07/06 Python
python使用PIL给图片添加文字生成海报示例
2018/08/17 Python
tensorflow-gpu安装的常见问题及解决方案
2020/01/20 Python
Python 之 Json序列化嵌套类方式
2020/02/27 Python
Python代码中如何读取键盘录入的值
2020/05/27 Python
全球性的众包图形设计市场:DesignCrowd
2021/02/02 全球购物
团委书记的竞聘演讲稿
2014/04/24 职场文书
员工趣味活动方案
2014/08/27 职场文书
领导干部民主生活会自我剖析材料范文
2014/09/20 职场文书
安全先进班组材料
2014/12/26 职场文书
给领导的感谢信范文
2015/01/23 职场文书
2016年学校综治宣传月活动总结
2016/03/16 职场文书
PHP中多字节字符串操作实例详解
2021/08/23 PHP
node快速搭建后台的实现步骤
2022/02/18 NodeJs