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 ctrl+Enter shift+Enter实现代码
Feb 07 Javascript
!DOCTYPE声明对JavaScript的影响分析
Apr 12 Javascript
AeroWindow 基于JQuery的弹出窗口插件
Jun 27 Javascript
Javascript this 的一些学习总结
Aug 31 Javascript
JS+DIV+CSS实现仿表单下拉列表效果
Aug 18 Javascript
jquery实现的用户注册表单提示操作效果代码分享
Aug 28 Javascript
微信小程序 swiper组件轮播图详解及实例
Nov 16 Javascript
AngularJS select设置默认值的实现方法
Aug 25 Javascript
Gulp实现静态网页模块化的方法详解
Jan 09 Javascript
vue.js绑定事件监听器示例【基于v-on事件绑定】
Jul 07 Javascript
vue 通过绑定事件获取当前行的id操作
Jul 27 Javascript
jquery实现异步文件上传ajaxfileupload.js
Oct 23 jQuery
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
超强分页类2.0发布,支持自定义风格,默认4种显示模式
2007/01/02 PHP
兼容性最强的PHP生成缩略图的函数代码(修改版)
2011/01/18 PHP
php切割页面div内容的实现代码分享
2012/07/31 PHP
php并发对MYSQL造成压力的解决方法
2013/02/21 PHP
php中cookie实现二级域名可访问操作的方法
2014/11/11 PHP
php中heredoc与nowdoc介绍
2014/12/25 PHP
php PDO实现的事务回滚示例
2017/03/23 PHP
laravel 框架配置404等异常页面
2019/01/07 PHP
javascript高级学习笔记整理
2011/08/14 Javascript
js移除事件 js绑定事件实例应用
2012/11/28 Javascript
window.open的页面如何刷新(父页面)上层页面
2012/12/28 Javascript
jQuery写的日历(包括日历的样式及功能)
2013/04/23 Javascript
jquery实现ajax提交form表单的方法总结
2014/03/03 Javascript
jQuery+PHP实现可编辑表格字段内容并实时保存
2015/10/09 Javascript
jquery自定义插件结合baiduTemplate.js实现异步刷新(附源码)
2016/12/22 Javascript
浅析vue数据绑定
2017/01/17 Javascript
node中koa中间件机制详解
2017/08/22 Javascript
Vue2.0用户权限控制解决方案
2017/11/29 Javascript
node.js用fs.rename强制重命名或移动文件夹的方法
2017/12/27 Javascript
Node.js命令行/批处理中如何更改Linux用户密码浅析
2018/07/22 Javascript
node.js 基于cheerio的爬虫工具的实现(需要登录权限的爬虫工具)
2019/04/10 Javascript
Python批量转换文件编码格式
2015/05/17 Python
对numpy中二进制格式的数据存储与读取方法详解
2018/11/01 Python
Python面向对象程序设计之类的定义与继承简单示例
2019/03/18 Python
python命令行工具Click快速掌握
2019/07/04 Python
TensorFlow2.0使用keras训练模型的实现
2021/02/20 Python
python实现发送邮件
2021/03/02 Python
施华洛世奇天猫官方旗舰店:SWAROVSKI
2017/04/17 全球购物
Eyeko美国:屡获殊荣的睫毛膏、眼线笔和眉妆
2018/07/05 全球购物
小米乌克兰网上商店:Xiaomi.UA
2019/10/29 全球购物
JDO的含义
2012/11/17 面试题
介绍一下Make? 为什么使用make
2013/12/08 面试题
毕业生自我鉴定
2013/11/05 职场文书
幼儿园中班下学期评语
2014/04/18 职场文书
《孙权劝学》教学反思
2014/04/23 职场文书
二人合伙经营协议书
2014/09/13 职场文书