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 类型转换方法
Oct 24 Javascript
鼠标事件的screenY,pageY,clientY,layerY,offsetY属性详解
Mar 12 Javascript
解决JS无法调用Controller问题的方法
Dec 31 Javascript
浅析JavaScript Array和string的转换(推荐)
May 20 Javascript
AngularJs实现分页功能不带省略号的代码
May 30 Javascript
AngularJS模板加载用法详解
Nov 04 Javascript
浅谈jQuery before和insertBefore的区别
Dec 04 Javascript
实例解析angularjs的filter过滤器
Dec 14 Javascript
easyui combotree加载静态数据问题(选不上)解决方法
Dec 26 Javascript
parabola.js抛物线与加入购物车效果的示例代码
Oct 25 Javascript
前端vue+elementUI如何实现记住密码功能
Sep 20 Javascript
Handtrack.js库实现实时监测手部运动(推荐)
Feb 08 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 地区分类排序算法
2013/07/01 PHP
PHP mysql事务问题实例分析
2016/01/18 PHP
php实现当前页面点击下载文件的简单方法
2016/09/22 PHP
PHP实现移除数组中为空或为某值元素的方法
2017/01/07 PHP
PHP实现本地图片转base64格式并上传
2020/05/29 PHP
greybox——不开新窗口看新的网页
2007/02/20 Javascript
jquery 表单取值常用代码
2009/12/22 Javascript
JavaScript接口实现代码 (Interfaces In JavaScript)
2010/06/11 Javascript
JqGrid web打印实现代码
2011/05/31 Javascript
JavaScript模板入门介绍
2012/09/26 Javascript
JS保留两位小数,多位小数的示例代码
2014/01/07 Javascript
超链接的禁用属性Disabled使用示例
2014/07/31 Javascript
JavaScript设计模式之策略模式实例
2014/10/10 Javascript
jQuery实现手机上输入后隐藏键盘功能
2017/01/04 Javascript
React Native中Navigator的使用方法示例
2017/10/13 Javascript
Bootstrap Table列宽拖动的方法
2018/08/15 Javascript
layui前端时间戳转化实例
2019/11/15 Javascript
Vue+webpack实现懒加载过程解析
2020/02/17 Javascript
详解node和ES6的模块导出与导入
2020/02/19 Javascript
[42:32]VP vs RNG 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
Python MySQLdb模块连接操作mysql数据库实例
2015/04/08 Python
九步学会Python装饰器
2015/05/09 Python
Python基于递归算法实现的走迷宫问题
2017/08/04 Python
用python写扫雷游戏实例代码分享
2018/05/27 Python
使用Python3+PyQT5+Pyserial 实现简单的串口工具方法
2019/02/13 Python
django中ORM模型常用的字段的使用方法
2019/03/05 Python
python对常见数据类型的遍历解析
2019/08/27 Python
Keras中的两种模型:Sequential和Model用法
2020/06/27 Python
英国最大的宠物商店:Pets at Home
2019/04/17 全球购物
main 函数执行以前,还会执行什么代码
2013/04/17 面试题
财务科科长岗位职责
2014/03/10 职场文书
节水倡议书范文
2014/04/15 职场文书
工程造价专业求职信
2014/07/17 职场文书
党员身份证明材料
2015/06/19 职场文书
结婚幸福感言
2015/08/01 职场文书
python百行代码实现汉服圈图片爬取
2021/11/23 Python