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 面向对象 重载
May 13 Javascript
用javascript为页面添加天气显示实现思路及代码
Dec 02 Javascript
a标签click和href执行顺序探讨
Jun 23 Javascript
浅析jQuery Ajax请求参数和返回数据的处理
Feb 24 Javascript
javascript创建对象的几种模式介绍
May 06 Javascript
Vue2.0 axios前后端登陆拦截器(实例讲解)
Oct 27 Javascript
ajax请求+vue.js渲染+页面加载的示例
Feb 11 Javascript
js控制随机数生成概率代码实例
Mar 21 Javascript
webpack4 SplitChunks实现代码分隔详解
May 23 Javascript
Vue实现微信支付功能遇到的坑
Jun 05 Javascript
浅谈vue使用axios的回调函数中this不指向vue实例,为undefined
Sep 21 Javascript
vue中三级导航的菜单权限控制
Mar 31 Vue.js
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 MSSQL 存储过程的方法
2008/12/24 PHP
php邮件发送,php发送邮件的类
2011/03/24 PHP
php使用PDO从数据库表中读取数据的实现方法(必看)
2017/06/02 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
JQuery 弹出框定位实现方法
2010/12/02 Javascript
JQuery表格内容过滤的实现方法
2013/07/05 Javascript
在Ubuntu上安装最新版本的Node.js
2014/07/14 Javascript
自己动手写的javascript前端等待控件
2015/10/30 Javascript
深入理解JavaScript程序中内存泄漏
2016/03/17 Javascript
BootStrap创建响应式导航条实例代码
2016/05/31 Javascript
javascript基础知识
2016/06/07 Javascript
微信小程序实现点击返回顶层的方法
2017/07/12 Javascript
简单的vuex 的使用案例笔记
2018/04/13 Javascript
JavaScript DOM元素常见操作详解【添加、删除、修改等】
2018/05/09 Javascript
微信小程序request请求封装,验签代码实例
2019/12/04 Javascript
Vue解决移动端弹窗滚动穿透问题
2020/12/15 Vue.js
Python中使用 Selenium 实现网页截图实例
2014/07/18 Python
python冒泡排序简单实现方法
2015/07/09 Python
window下eclipse安装python插件教程
2017/04/24 Python
Python中存取文件的4种不同操作
2018/07/02 Python
Sanic框架蓝图用法实例分析
2018/07/17 Python
Python中flatten( )函数及函数用法详解
2018/11/02 Python
python版本五子棋的实现代码
2018/12/11 Python
Python数据报表之Excel操作模块用法分析
2019/03/11 Python
python 判断字符串中是否含有汉字或非汉字的实例
2019/07/15 Python
python django下载大的csv文件实现方法分析
2019/07/19 Python
Python如何使用队列方式实现多线程爬虫
2020/05/12 Python
Numpy数组的广播机制的实现
2020/11/03 Python
ALDO美国官网:加拿大女鞋品牌
2018/12/28 全球购物
static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
2015/02/22 面试题
改革共识倡议书
2014/08/29 职场文书
法人身份证明书
2014/10/08 职场文书
2015年音乐教学工作总结
2015/07/22 职场文书
婚礼家长致辞
2015/07/27 职场文书
导游词之井冈山
2019/11/20 职场文书
win7配置本地ftp服务器的图文教程
2022/08/05 Servers