zoukankan      html  css  js  c++  java
  • 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);
    

      

  • 相关阅读:
    Go基础系列:流程控制结构
    Go基础系列:数据类型转换(strconv包)
    Go基础系列:简单数据类型
    Go基础系列:常量和变量
    Go基础系列:map类型
    Go基础系列:Go slice详解
    go基础系列:数组
    Go基础系列:import导包和初始化阶段
    Go基础系列:构建go程序
    go基础系列:结构struct
  • 原文地址:https://www.cnblogs.com/shanlu0000/p/13151811.html
Copyright © 2011-2022 走看看