HTTP,URL,FS 模块搭建一个静态WEB服务器

WEB服务器:

一般指网站服务器,是指驻留在因特网上某种类型计算机的程序,可以向浏览器等Web 客户端提供文档,也可以放置网站文件让全世界浏览,还可以放置数据文件,让全世界下载,目前最主流的Web服务器有 Apache,Nginx,IIS等。

NodeJS 创建一个WEB服务器,

可以让我们访问Web服务器上面的网站

可以让我们下载Web服务器上面的文件

把static 目录下的 html,css,js,json等静态资源放在服务器上被浏览器读取

1,通过 fs 模块读取static 目录下的所有文件,需要现获取地址

const http = require('http');
const fs = require('fs')

http.createServer(function (request, response) {
  //1,通过fs模块读取static目录下的文件
  let pathname = request.url  //先获取地址
  pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页
  console.log(path) 
  if (pathname!='/favicon.ico'){//过滤favicon的请求再读取
      fs.readFile('./static'+pathname,(err,data)=>{
         if(err){
             response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' });
             response.end('<h3>404</h3>');
         }
         else{
             response.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' });
             response.end(data);
         }
      })
  }
}).listen(8081);

  浏览器中地址栏中输入:http://127.0.0.1:8081/login.html ,会打印 /login.html 和 /favicon.ico,输入http://127.0.0.1:8081/index.html 会打印 /index.html 和 /favicon.ico ,所以可以过滤掉 /favicon.ico 这个请求,并且,当路径为 http://127.0.0.1:8081 时,path 为根目录 / ,可以定为到首页。

  但这时会有报错:

  

   json文件以及页面样式文件等等都无法加载,这是因为,我们读取的文件类型都是 text/html ,css和js等文件都以这种文件类型读取是不合适的,需要做相应的修改

  

   

   这里需要根据文件后缀修改

2,根据后缀名设置不同的文件类型:

  引入path模块,通过 paht模块的 extname() 方法可以获取文件后缀名

const http = require('http');
const fs = require('fs')
const path = require('path')

http.createServer(function (request, response) {
  //1,通过fs模块读取static目录下的文件
  let pathname = request.url  //先获取地址
  pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页
  //console.log(path) 
  let ext=path.extname(pathname) //获取文件后缀名
  console.log(ext)
  if (pathname!='/favicon.ico'){//过滤favicon的请求再读取
      fs.readFile('./static'+pathname,(err,data)=>{
         if(err){
             response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' });
             response.end('<h3>404</h3>');
         }
         else{
             response.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' });
             response.end(data);
         }
      })
  }
}).listen(8081);

对于JSON文件,只需要保留.json,使用 url 模块,解析 url

接着定义一个设置文件类型的方法,并暴露出去,在读取文件时调用:

getMime.js :

exports.getMime=function(ext){
    switch(ext){
        case '.html':
            return 'text/html'
        case '.css':
            return 'text/css'
        case '.js':
            return 'text/javascript'
        default:
            return 'text/html'
    }
}

web.js 外部调用这个模块中的 getMime 方法

const http = require('http');
const fs = require('fs')
const path = require('path')
const url = require('url')
const util = require('./utils/util')

http.createServer(function (request, response) {
  //1,通过fs模块读取static目录下的文件
  let pathname = url.parse(request.url).pathname  //先获取地址
  //console.log(pathname)
  pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页
  //console.log(pathname) /** /index.html  */
  let ext=path.extname(pathname) //获取文件后缀名
  //console.log(ext) /**.html */
  let mime = util.getMime(ext) //获取文件类型
  //console.log(mime) /** text/html */
  if (pathname!='/favicon.ico'){//过滤favicon的请求再读取
      fs.readFile('./static'+pathname,(err,data)=>{
         if(err){
             response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' });
             response.end('<h3>404</h3>');
         }
         else{
             response.writeHead(200, { 'Content-Type': `${mime};charset="utf-8"` }); //es6模板字符串方式
             //response.writeHead(200, { 'Content-Type': '' + mime + ';charset="utf-8"' }); //字符串拼接方式
             response.end(data);
         }
      })
  }
}).listen(8081);

现在可以加载出 css , js 文件了

为了支持更多文件类型的加载,引入一个 mime.json 文件,在设置文件类型的模块中读取这个文件:

mime.json

getMime.js 模块中需要异步读取这个文件,有两种方式,

方式一:通过 promise,返回一个promise对象,在web.js 中使用 async 和 await 读取返回的promise的返回值,

util 模块暴露出的 getMime 方法

const fs = require('fs')
exports.getMime = function (ext) {
    return new Promise((resolve,reject)=>{
        fs.readFile('./utils/mime.json',(err,data)=>{ //注意路径相对于根目录
            if(err){
                console.log("读取失败")
                reject(err)
            }
            else{
                //console.log(data); //buffer
                //console.log(data.toString()) //".css":"text/css"
                //console.log(JSON.parse(data.toString())) // '.css':'text/css'
                //console.log(JSON.parse(data.toString())[ext]) //text/css 
                let mime = JSON.parse(data.toString())[ext]
                resolve(mime)
            }
        })
    })
}

外部调用:

const http = require('http');
const fs = require('fs')
const path = require('path')
const url = require('url')
const util = require('./utils/util')

http.createServer(function (request, response) {
  let pathname = url.parse(request.url).pathname  //先获取地址
  pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页
  let ext=path.extname(pathname) //获取文件后缀名
  if (pathname!='/favicon.ico'){//过滤favicon的请求再读取
      fs.readFile('./static'+pathname,async (err,data)=>{
         if(err){
             response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' });
             response.end('<h3>404</h3>');
         }
         else{
             let mime = await util.getMime(ext) //获取文件类型
             response.writeHead(200, { 'Content-Type': `${mime};charset="utf-8"` }); 
             response.end(data);
         }
      })
  }
}).listen(8081);

方式二,直接使用 fs.readFileSync 同步读取文件,读取完成才进行下一步操作:

const fs = require('fs')
exports.getMime = function (ext) {
    let data=fs.readFileSync('./utils/mime.json'); //同步方法,没有回调
    let mime = JSON.parse(data.toString())[ext]
    return mime;
}

外部调用:

const http = require('http');
const fs = require('fs')
const path = require('path')
const url = require('url')
const util = require('./utils/util')

http.createServer(function (request, response) {
  let pathname = url.parse(request.url).pathname  //先获取地址
  pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页
  let ext=path.extname(pathname) //获取文件后缀名
  if (pathname!='/favicon.ico'){//过滤favicon的请求再读取
      fs.readFile('./static'+pathname,(err,data)=>{
          if (err) {
              response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' });
              response.end('<h3>404</h3>');
          }
          else {
              let mime = util.getMime(ext) //获取文件类型
              response.writeHead(200, { 'Content-Type': `${mime};charset="utf-8"` });
              response.end(data);
          }
      })
  }
}).listen(8081);

两种方式,都可以使浏览器加载各种类型资源文件:

 

 封装创建静态web服务

web.js

const fs = require('fs')
const path = require('path')
const url = require('url')

let getMime = function (ext) {
    let data = fs.readFileSync('./mime.json'); //同步方法,没有回调
    let mime = JSON.parse(data.toString())[ext]
    return mime;
}

module.exports = function staticWeb(req,res,staticPath){
    let pathname = url.parse(req.url).pathname  //先获取地址
    pathname = pathname == '/' ? '/index.html' : pathname //根目录下定位到首页
    let ext = path.extname(pathname) //获取文件后缀名
    if (pathname != '/favicon.ico') {//过滤favicon的请求再读取
        fs.readFile(staticPath + pathname, (err, data) => {
            if (err) {
                res.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' });
                res.end('<h3>404</h3>');
            }
            else {
                let mime = getMime(ext) //获取文件类型
                res.writeHead(200, { 'Content-Type': `${mime};charset="utf-8"` });
                res.end(data);
            }
        })
    }
}

test.js ,只需要传入 req , res , 和静态资源目录即可:

const http = require('http');
const staticWeb = require('./web')

http.createServer(function (request, response) {
    staticWeb(request,response,'./static')
}).listen(8081);

  

 

posted @ 2021-02-02 00:18  shanlu  阅读(321)  评论(0编辑  收藏  举报