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的朋友一点学习经验小结
Nov 23 Javascript
jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明
Jun 27 Javascript
js实现字符串的16进制编码不加密
Apr 25 Javascript
JavaScript对象属性检查、增加、删除、访问操作实例
Jul 08 Javascript
Bootstrap轮播图学习使用
Feb 10 Javascript
vue.js实现刷新当前页面的方法教程
Jul 05 Javascript
微信小程序获取手机网络状态的方法【附源码下载】
Dec 08 Javascript
vue.js实现点击后动态添加class及删除同级class的实现代码
Apr 04 Javascript
使用D3.js构建实时图形的示例代码
Aug 28 Javascript
JS中的函数与对象的创建方式
May 12 Javascript
微信小程序 select 下拉框组件功能
Sep 09 Javascript
vue学习笔记之Vue中css动画原理简单示例
Feb 29 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连接mssql:pdo odbc sql server
2011/07/20 PHP
PHP调用Webservice实例代码
2011/07/29 PHP
laravel 出现command not found问题的解决方案
2019/10/23 PHP
JavaScript小技巧 2.5 则
2010/09/12 Javascript
web前端开发也需要日志
2010/12/09 Javascript
jQuery总体架构的理解分析
2011/03/07 Javascript
js异步加载的三种解决方案
2013/03/04 Javascript
谈谈关于JavaScript 中的 MVC 模式
2013/04/11 Javascript
浅析Js(Jquery)中,字符串与JSON格式互相转换的示例(直接运行实例)
2013/07/09 Javascript
js文件Cookie存取值示例代码
2014/02/20 Javascript
Node.js 制作实时多人游戏框架
2015/01/08 Javascript
javascript实现英文首字母大写
2015/04/23 Javascript
使用JQuery在线制作ppt并在线演示源码特效
2015/09/08 Javascript
JSON遍历方式实例总结
2015/12/07 Javascript
jQuery validate插件实现ajax验证重复的2种方法
2016/01/22 Javascript
基于Vue实现后台系统权限控制的示例代码
2017/08/29 Javascript
详解基于electron制作一个node压缩图片的桌面应用
2019/01/29 Javascript
Vue项目总结之webpack常规打包优化方案
2019/06/06 Javascript
如何在项目中使用log4.js的方法步骤
2019/07/16 Javascript
layui 阻止图片上传的实例(before方法)
2019/09/26 Javascript
原生JavaScript实现进度条
2021/02/19 Javascript
[01:42]辉夜杯战队访谈宣传片—FANTUAN
2015/12/25 DOTA
[02:03]永远的信仰DOTA2 中国军团历届国际邀请赛回顾
2016/06/26 DOTA
Python爬取三国演义的实现方法
2016/09/12 Python
Python正则表达式经典入门教程
2017/05/22 Python
解决pandas read_csv 读取中文列标题文件报错的问题
2018/06/15 Python
python实现超级马里奥
2020/03/18 Python
python 实现倒计时功能(gui界面)
2020/11/11 Python
Django url 路由匹配过程详解
2021/01/22 Python
美国著名的品牌折扣店:Burlington
2017/06/08 全球购物
Hoover胡佛官网:美国吸尘器和洗地机品牌
2019/01/09 全球购物
cf收人广告词大全
2014/03/14 职场文书
关于运动会的广播稿50字
2014/10/17 职场文书
2014年学校安全工作总结
2014/11/13 职场文书
党支部考察鉴定意见
2015/06/02 职场文书
新员工实习期个人工作总结
2015/10/15 职场文书