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 相关文章推荐
仿163填写邮件地址自动显示下拉(无优化)
Nov 05 Javascript
jquery $(document).ready() 与window.onload的区别
Dec 28 Javascript
Javascript 中的 &amp;&amp; 和 || 使用小结
Apr 25 Javascript
JavaScript prototype属性深入介绍
Nov 27 Javascript
在Javascript中处理数组之toSource()方法的使用
Jun 09 Javascript
完美解决手机网页中输入框被输入法遮挡的问题
Dec 19 Javascript
详解js类型判断
May 22 Javascript
Vue EventBus自定义组件事件传递
Jun 25 Javascript
jQuery实现表单动态添加与删除数据操作示例
Jul 03 jQuery
20多个小事例带你重温ES10新特性(小结)
Sep 29 Javascript
vue实现拖拽效果
Dec 23 Javascript
80行代码写一个Webpack插件并发布到npm
May 24 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实现微信发红包程序
2015/08/24 PHP
Laravel 框架基于自带的用户系统实现登录注册及错误处理功能分析
2020/04/14 PHP
jQuery第三课 修改元素属性及内容的代码
2010/03/14 Javascript
超酷的网页音乐播放器DewPlayer使用方法
2010/12/18 Javascript
JavaScript 注册事件代码
2011/01/27 Javascript
jquery 获取标签名(tagName)示例代码
2013/07/11 Javascript
ZeroClipboard插件实现多浏览器复制功能(支持firefox、chrome、ie6)
2014/08/30 Javascript
node.js中的fs.realpathSync方法使用说明
2014/12/16 Javascript
轻松使用jQuery双向select控件Bootstrap Dual Listbox
2015/12/13 Javascript
原生Javascript插件开发实践
2017/01/09 Javascript
jQuery基于ajax实现页面加载后检查用户登录状态的方法
2017/02/10 Javascript
AngularJS前端页面操作之用户修改密码功能示例
2017/03/27 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(上)
2017/04/21 Javascript
React简单介绍
2017/05/24 Javascript
JS简单实现父子窗口传值功能示例【未使用iframe框架】
2017/09/20 Javascript
NodeJS实现视频转码的示例代码
2017/11/18 NodeJs
bootstrap3中container与container_fluid外层容器的区别讲解
2017/12/04 Javascript
JS中创建自定义类型的常用模式总结【工厂模式,构造函数模式,原型模式,动态原型模式等】
2019/01/19 Javascript
Vue实现简单计算器
2021/01/20 Vue.js
Django Docker容器化部署之Django-Docker本地部署
2019/10/09 Python
django框架ModelForm组件用法详解
2019/12/11 Python
Pytorch 中retain_graph的用法详解
2020/01/07 Python
flask框架蓝图和子域名配置详解
2020/01/25 Python
Python 窗体(tkinter)下拉列表框(Combobox)实例
2020/03/04 Python
伦敦时尚生活的缩影:LN-CC
2017/01/24 全球购物
给医务人员表扬信
2014/01/12 职场文书
工作汇报开头与结尾怎么写
2014/11/08 职场文书
2014年财务科工作总结
2014/11/11 职场文书
2014年图书馆个人工作总结
2014/12/18 职场文书
辩论赛主持人开场白
2015/05/29 职场文书
学雷锋活动简报
2015/07/20 职场文书
CSS精灵图的原理与使用方法介绍
2022/03/17 HTML / CSS
Python借助with语句实现代码段只执行有限次
2022/03/23 Python
Elasticsearch 配置详解
2022/04/19 Java/Android
笔记本自带的win11如何跳过联网激活?
2022/04/20 数码科技
SQL Server2019安装的详细步骤实战记录(亲测可用)
2022/06/10 SQL Server