欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于node.js的静态资源服务器

程序员文章站 2022-06-19 15:36:40
最近碰见了一个面试题 手撸一个基于node的静态资源服务器。以下是我个人的思路直接先贴代码const http = require('http')const fs = require('fs')const path = require('path')const server = http.createServer()server.on('request', (req, res) => { res.setHeader('Access-Control-Allow-Origin', '*'...

最近碰见了一个面试题 手撸一个基于node的静态资源服务器。以下是我个人的思路

直接先贴代码

const http = require('http')
const fs = require('fs')
const path = require('path')
const server = http.createServer()

server.on('request', (req, res) => {
  res.setHeader('Access-Control-Allow-Origin', '*') // 设置跨域
  controllers(req, res)
  // readStatic(url, res)
})
// 4.启动服务器
server.listen(8080, () => {
  console.log('start is server')
})

let redis = {}

setInterval(() => { // 用定时器有点草率但是没时间了 先这样凑合做个简单的清楚
  redis = {} // 时间够的话 指定不会这样清,会对每个key进行一个时间绑定。如果时间到期则回清除 类似于session
}, 3000)

const controllers = async (req, res) => {
  const url = req.url
  if (url === '/favicon.ico') return
  if (url === '/') {
    const files = await getFilesName()
    res.writeHead(200, { 'Content-Type': 'text/html;charset=utf-8' })
    let str = ''
    for (var i = 0; i < files.length; i++) {
      str = str + `<a href=${files[i]}>${files[i]}</a><br>`
    }
    const query = 'https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js'
    res.end(`<body><div id='router'></div></body><script src="${query}"></script><script> document.getElementById('router').innerHTML ='${str}'</script> `)
    res.end(`<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        let domA = document.getElementsByTagName("a")
        for(var i=0;i<domA.length;i++){
          let url = http://localhost:8080/+ domA[i].innerHTML
          domA[i].onclick = function(){
            $.ajax({url:url,type:'GET',success:function(data){
              console.log(data)
            }})
          }
        }
    </script>`)
  } else {
    readStatic(url, res)
  }
}

const readStatic = function (url, res) {
  fs.readFile(path.join(__dirname, 'static', url), (_err, data) => { // 路径拼接去static目录下找对应的文件
    const urlItem = url.split('.')
    const Contenttype = mime[urlItem[1]] || 'application/octet-stream'

    if (urlItem[1] === undefined) {
      if (!redis[url]) {
        res.writeHead(200, {
          'Content-Type': 'application/octet-stream',
          'Content-Disposition': `attachment; filename=${urlItem[0]}`
        })
        fs.createReadStream(`${__dirname}/static${url}`).pipe(res)
        redis[url] = true
      } else {
        res.writeHead(403, { 'Content-type': Contenttype })
        res.end()
      }
    } else {
      res.writeHead(200, { 'Content-Type': Contenttype + ';charset=utf-8' })
      res.end(data)
    }
  })
}

const getFilesName = () => {
  return new Promise((resolve, reject) => {
    fs.readdir(`${__dirname}/static`, function (_err, data) {
      if (_err) {
        return reject(_err)
      }
      const item = []
      for (const value of data) {
        item.push(value)
      }
      resolve(item)
    })
  })
}

// const isBuffer = function (str) {
//   return str && typeof str === 'object' && Buffer.isBuffer(str)
// }

const mime = {
  css: 'text/css',
  gif: 'image/gif',
  html: 'text/html',
  ico: 'image/x-icon',
  jpeg: 'image/jpeg',
  jpg: 'image/jpeg',
  js: 'text/javascript',
  json: 'application/json',
  pdf: 'application/pdf',
  png: 'image/png',
  svg: 'image/svg+xml',
  swf: 'application/x-shockwave-flash',
  tiff: 'image/tiff',
  txt: 'text/plain',
  wav: 'audio/x-wav',
  wma: 'audio/x-ms-wma',
  wmv: 'video/x-ms-wmv',
  xml: 'text/xml'
}

  • 首先需要建立一个app.js文件,该文件主要用于搭建服务器,所谓的静态资源服务器就是把服务器上的文件通过http进行发送或者说是做处理
  • 比如通过请求某个地址需要把某个文件夹下面的html渲染在浏览器上,或者说下载某个文件,也或者说把某个文件夹下面的txt文件的内容显示在浏览器上。html的渲染不是显示源码而是显示的是网页
  • 主文件app.js建立好后就需要 建一个静态文件夹用于放我们需要显示或者下载的文件

基于node.js的静态资源服务器

  • 我的目录,我在static下面放了四个类型不一样的文件,我的目的是通过请求/index.js路径就显示源码在网页,请求/index.html就把html渲染在网页,/index就是直接下载该文件

  • 首先需要搭个基本的服务器 这个时候就会用到http模块 ,服务器搭建完成后

  • 我的做法是通过后缀名去区分不同的文件,通过区分不同的文件给他设置对应的content-type类型
    -基于node.js的静态资源服务器

  • 一些类型都封装在mine对象中

  • 基于node.js的静态资源服务器

  • 还有一个需求则是把根目录下的文件当做a标签一样点击后进行不同的操作,其实就是点击后发送ajax请求,当用户请求127.0.0.1:8080/路径的时候我会返他一个我自己的html页面这个页面是会显示static目录下的文件如图
    基于node.js的静态资源服务器

  • 其实就是MVC的模板渲染我这个是最基础的,如果你把Html当做字符串返回在浏览器上和本地加载html是一样的但是 content-type得设成 text/html 否则浏览器是不会知道你给他了一个什么东西,这里偷了个懒 引入了百度的jquery写了个ajax请求。没有直接写原生的XMLHttpRequest

基于node.js的静态资源服务器

总结:其实就是构建一个Http服务然后在本地建立一个static的静态资源库,然后通过fs文件操作来进行数据返回,根据不同的需求返回不同的结果。难点在于对http的content-type的理解,写的时候因为不熟悉踩了不少坑。这个代码还可以继续的优化。考察的就是代码能力,可惜,平时库用太多忘了http.js的操作和content-type的设置,其实如果扩展起来就类似于nginx的功能。 还是太菜没抓住机会!

码云地址:https://gitee.com/gong-yongchao/static-server

本文地址:https://blog.csdn.net/a519637560/article/details/109645217

相关标签: node.js http