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实现无间缝滚动示例
Jan 28 Javascript
JS比较2个日期间隔的示例代码
Apr 15 Javascript
JavaScript实现大数的运算
Nov 24 Javascript
在JavaScript的AngularJS库中进行单元测试的方法
Jun 23 Javascript
1秒50万字!js实现关键词匹配
Aug 01 Javascript
基于JavaScript实现瀑布流效果
Mar 29 Javascript
JavaScript基于replace+正则实现ES6的字符串模版功能
Apr 25 Javascript
Vue.js鼠标悬浮更换图片功能
May 17 Javascript
jQuery实现遍历XML节点和属性的方法示例
Apr 29 jQuery
jQuery实现动态加载select下拉列表项功能示例
May 31 jQuery
详解Axios统一错误处理与后置
Sep 26 Javascript
vue element ui validate 主动触发错误提示操作
Sep 21 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的面试题集
2006/11/19 PHP
Laravel框架使用Seeder实现自动填充数据功能
2018/06/13 PHP
thinkphp5框架调用其它控制器方法 实现自定义跳转界面功能示例
2019/07/03 PHP
强制设为首页代码
2006/06/19 Javascript
jQuery 全选效果实现代码
2009/03/23 Javascript
javascript面向对象之二 命名空间
2011/02/08 Javascript
Json字符串转换为JS对象的高效方法实例
2013/05/01 Javascript
js 实现日期灵活格式化的小例子
2013/07/14 Javascript
再谈javascript原型继承
2014/11/10 Javascript
JQuery勾选指定name的复选框集合并显示的方法
2015/05/18 Javascript
详解JavaScript对W3C DOM模版的支持情况
2015/06/16 Javascript
jQuery获取父元素节点、子元素节点及兄弟元素节点的方法
2016/04/14 Javascript
Vue 中的compile操作方法
2018/02/26 Javascript
webpack+vue-cli项目中引入外部非模块格式js的方法
2018/09/28 Javascript
详解vue-router数据加载与缓存使用总结
2018/10/29 Javascript
vue 表单验证按钮事件交由父组件触发的方法
2018/12/17 Javascript
vue中轮训器的使用
2019/01/27 Javascript
使用flow来规范javascript的变量类型
2019/09/12 Javascript
[00:32]DOTA2上海特级锦标赛 COL战队宣传片
2016/03/04 DOTA
以911新闻为例演示Python实现数据可视化的教程
2015/04/23 Python
九步学会Python装饰器
2015/05/09 Python
使用Python处理Excel表格的简单方法
2018/06/07 Python
python利用百度AI实现文字识别功能
2018/11/27 Python
python实现扫描ip地址的小程序
2019/04/16 Python
Python线程协作threading.Condition实现过程解析
2020/03/12 Python
解决matplotlib.pyplot在Jupyter notebook中不显示图像问题
2020/04/22 Python
汇集了世界上最好的天然和有机美容产品:LoveLula
2018/02/05 全球购物
英国独特家具和家庭用品购物网站:Cuckooland
2020/08/30 全球购物
创联软件面试题笔试题
2012/10/07 面试题
计算机大学生的自我评价
2013/10/15 职场文书
审计局2014法制宣传日活动总结
2014/11/01 职场文书
2015年世界粮食日演讲稿
2015/03/20 职场文书
2015年初中教务处工作总结
2015/07/21 职场文书
一个家长教育孩子的心得体会
2016/01/15 职场文书
OpenCV实现常见的四种图像几何变换
2022/04/01 Python
Windows7下FTP搭建图文教程
2022/08/05 Servers