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 11 Javascript
JQuery从头学起第三讲
Jul 06 Javascript
js模拟滚动条(横向竖向)
Feb 22 Javascript
jquery toolbar与网页浮动工具条具体实现代码
Jan 12 Javascript
JS比较2个日期间隔的示例代码
Apr 15 Javascript
JavaScript事件学习小结(三)js事件对象
Jun 09 Javascript
JS实现pasteHTML兼容ie,firefox,chrome的方法
Jun 22 Javascript
angular指令笔记ng-options的使用方法
Sep 18 Javascript
JS返回顶部实例代码
Aug 09 Javascript
基于vue实现分页效果
Nov 06 Javascript
JavaScript 点击触发复制功能实例详解
Nov 02 Javascript
angularjs http与后台交互的实现示例
Dec 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使用CURL实现多线程抓取网页
2015/04/30 PHP
浅析php静态方法与非静态方法的用法区别
2016/05/17 PHP
PHP简单实现数字分页功能示例
2016/08/24 PHP
Laravel接收前端ajax传来的数据的实例代码
2017/07/20 PHP
php进程(线程)通信基础之System V共享内存简单实例分析
2019/11/09 PHP
jQuery 瀑布流 浮动布局(一)(延迟AJAX加载图片)
2012/05/23 Javascript
jQuery.query.js 取参数的两点问题分析
2012/08/06 Javascript
jquery动画3.创建一个带遮罩效果的图片走廊
2012/08/24 Javascript
js中小数转换整数的方法
2014/01/26 Javascript
js实现图片旋转的三种方法
2014/04/10 Javascript
jQuery同步提交示例代码
2015/12/12 Javascript
JS封装的自动创建表格的实现代码
2016/06/15 Javascript
微信小程序 教程之wxapp 视图容器 view
2016/10/19 Javascript
详解React-Todos入门例子
2016/11/08 Javascript
JS正则表达式修饰符中multiline(/m)用法分析
2016/12/27 Javascript
AngularJs中 ng-repeat指令中实现含有自定义指令的动态html的方法
2017/01/19 Javascript
JavaScript省市级联下拉菜单实例
2017/02/14 Javascript
bootstrap为水平排列的表单和内联表单设置可选的图标
2017/02/15 Javascript
微信小程序之GET请求的实例详解
2017/09/29 Javascript
JS实现的JSON序列化操作简单示例
2018/07/02 Javascript
vue展示dicom文件医疗系统的实现代码
2018/08/27 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
2020/05/30 jQuery
Threejs实现滴滴官网首页地球动画功能
2020/07/13 Javascript
vue+Element-ui实现登录注册表单
2020/11/17 Javascript
Python 实现平台类游戏添加跳跃功能
2020/03/27 Python
python交互模式基础知识点学习
2020/06/18 Python
python pandas dataframe 去重函数的具体使用
2020/07/20 Python
推荐值得学习的12款python-web开发框架
2020/08/10 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
matplotlib之属性组合包(cycler)的使用
2021/02/24 Python
中级会计职业生涯规划范文
2014/01/16 职场文书
大学运动会通讯稿
2014/01/28 职场文书
小学数学课后反思
2014/04/23 职场文书
医生个人自我剖析材料
2014/10/08 职场文书
2015年七年级班主任工作总结
2015/05/21 职场文书
新学期家长寄语2016
2015/12/03 职场文书