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 相关文章推荐
读jQuery之九 一些瑕疵说明
Jun 21 Javascript
Javascript 检测键盘按键信息及键码值对应介绍
Jan 03 Javascript
js中eval()函数和trim()去掉字符串左右空格应用
Feb 02 Javascript
JavaScript中判断对象类型的几种方法总结
Nov 11 Javascript
window.print打印指定div指定网页指定区域的方法
Aug 04 Javascript
使用js复制链接中的部分文字的方法
Jul 30 Javascript
将JSON字符串转换成Map对象的方法
Nov 30 Javascript
实现点击下箭头变上箭头来回切换的两种方法【推荐】
Dec 14 Javascript
jQuery实现select下拉框获取当前选中文本、值、索引
May 08 jQuery
微信小程序实现团购或秒杀批量倒计时
Nov 01 Javascript
微信小程序自定义select下拉选项框组件的实现代码
Aug 28 Javascript
JS实现图片轮播效果实例详解【可自动和手动】
Apr 04 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错误Parse error: syntax error, unexpected end of file in test.php on line 12解决方法
2014/06/23 PHP
php实现utf-8转unicode函数分享
2015/01/06 PHP
PHP echo()函数讲解
2019/02/15 PHP
extjs grid设置某列背景颜色和字体颜色的方法
2010/09/03 Javascript
导入extjs、jquery 文件时$使用冲突问题解决方法
2014/01/14 Javascript
将HTML格式的String转化为HTMLElement的实现方法
2014/08/07 Javascript
js实现的黑背景灰色二级导航菜单效果代码
2015/08/24 Javascript
轻松学习jQuery插件EasyUI EasyUI创建树形网络(1)
2015/11/30 Javascript
JS动态改变浏览器标题的方法
2016/04/06 Javascript
jQuery获取访问者IP地址的方法(基于新浪API与QQ查询接口)
2016/05/25 Javascript
jquery实现上传文件大小类型的验证例子(推荐)
2016/06/25 Javascript
封装的dialog插件 基于bootstrap模态对话框的简单扩展
2016/08/10 Javascript
AngularJS+Bootstrap实现多文件上传与管理
2016/11/08 Javascript
JS基于正则表达式的替换操作(replace)用法示例
2017/04/28 Javascript
angularJs-$http实现百度搜索时的动态下拉框示例
2018/02/27 Javascript
vue如何在自定义组件中使用v-model
2018/05/14 Javascript
js实现各浏览器全屏代码实例
2018/07/03 Javascript
解决layer图标icon不加载的问题
2019/09/04 Javascript
element-ui点击查看大图的方法示例
2020/12/14 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
使用Python3中的gettext模块翻译Python源码以支持多语言
2015/03/31 Python
分分钟入门python语言
2018/03/20 Python
python定时关机小脚本
2018/06/20 Python
将python包发布到PyPI和制作whl文件方式
2019/12/25 Python
python UDF 实现对csv批量md5加密操作
2021/01/01 Python
将HTML5 Canvas的内容保存为图片借助toDataURL实现
2013/05/20 HTML / CSS
HTML5新增元素如何兼容旧浏览器有哪些方法
2014/05/09 HTML / CSS
新西兰最大的品牌运动鞋购物网站:Platypus NZ
2017/10/27 全球购物
危爆物品安全大检查大整治工作方案
2014/05/03 职场文书
大学生工作自荐书
2014/06/16 职场文书
学校领导班子对照检查材料
2014/09/24 职场文书
党的群众路线教育实践活动总结材料
2014/10/30 职场文书
学前班语言教学计划
2015/01/20 职场文书
MySQL优化之如何写出高质量sql语句
2021/05/17 MySQL
vue使用Google Recaptcha验证的实现示例
2021/08/23 Vue.js
详解redis在微服务领域的贡献
2021/10/16 Redis