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 相关文章推荐
使用Browserify配合jQuery进行编程的超级指南
Jul 28 Javascript
微信小程序  audio音频播放详解及实例
Nov 02 Javascript
浅谈js数组和splice的用法
Dec 04 Javascript
bootstrap栅格系统示例代码分享
May 22 Javascript
js禁止Backspace键使浏览器后退的实现方法
Sep 01 Javascript
Bootstrap 3多级下拉菜单实例
Nov 23 Javascript
详解Express笔记之动态渲染HTML(新手入坑)
Dec 13 Javascript
JavaScript实现获取两个排序数组的中位数算法示例
Feb 26 Javascript
浅谈VUE防抖与节流的最佳解决方案(函数式组件)
May 22 Javascript
vue监听滚动事件的方法
Dec 21 Vue.js
Node与Python 双向通信的实现代码
Jul 16 Javascript
JavaScript 原型与原型链详情
Nov 02 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 方便水印和缩略图的图形类
2009/05/21 PHP
php cookie使用方法学习笔记分享
2013/11/07 PHP
PHP 二维数组和三维数组的过滤
2016/03/16 PHP
Laravel5.5以下版本中如何自定义日志行为详解
2018/08/01 PHP
PHP Redis扩展无法加载的问题解决方法
2019/08/22 PHP
JavaScript进阶教程(第四课第一部分)
2007/04/05 Javascript
html+css+js实现xp window界面及有关功能
2013/03/26 Javascript
JavaScript?Apple设备检测示例代码
2013/11/15 Javascript
jquery fancybox ie6不显示关闭按钮的解决办法
2013/12/25 Javascript
Node.js 异步编程之 Callback介绍(一)
2015/03/30 Javascript
js闭包所用的场合以及优缺点分析
2015/06/22 Javascript
javascript实现表单验证
2016/01/29 Javascript
js实现将json数组显示前台table中
2017/01/10 Javascript
JavaScript提高加载和执行效率的方法
2017/02/03 Javascript
微信小程序实现登录页云层漂浮的动画效果
2017/05/05 Javascript
详解webpack打包vue时提取css
2017/05/26 Javascript
vue组件父子间通信详解(三)
2017/11/07 Javascript
详解利用eventemitter2实现Vue组件通信
2019/11/04 Javascript
javascript Canvas动态粒子连线
2020/01/01 Javascript
javascript canvas检测小球碰撞
2020/04/17 Javascript
JavaScript 接口原理与用法实例详解
2020/05/12 Javascript
vue props 一次传多个值实例
2020/07/22 Javascript
Ant design vue中的联动选择取消操作
2020/10/31 Javascript
详细解析Python当中的数据类型和变量
2015/04/25 Python
python类和继承用法实例
2015/07/07 Python
轻松理解Python 中的 descriptor
2017/09/15 Python
Django基于ORM操作数据库的方法详解
2018/03/27 Python
详解python 3.6 安装json 模块(simplejson)
2019/04/02 Python
PyTorch和Keras计算模型参数的例子
2020/01/02 Python
Python多线程thread及模块使用实例
2020/04/28 Python
美国隐形眼镜网上商店:Lens.com
2019/09/03 全球购物
教代会开幕词
2015/01/28 职场文书
物业保洁员管理制度
2015/08/05 职场文书
2015年幼儿园班主任个人工作总结
2015/10/22 职场文书
源码解读Spring-Integration执行过程
2021/06/11 Java/Android
SQL Server远程连接的设置步骤(图文)
2022/03/23 SQL Server