美文网首页饥人谷技术博客
如何搭建一个简单的静态服务器

如何搭建一个简单的静态服务器

作者: clumsy钧 | 来源:发表于2018-08-24 23:59 被阅读3次

    搭建的基本结构

    var http = require('http')//创建服务器模块
    
    var server = http.createServer(function(req, res){
        console.log('hellow')
        res.setHeader("Content-Type","text/html; charset=utf-8")
        res.write('<h1> 大家好</h1>')
        res.end()//响应结束
    })//建立服务器
    server.listen(9000)//设置服务器端口
    

    搭建的思路

    通过request得到url
    得到url之后可以得到文件路径
    在本地就可以读取文件内容当成字符串发给浏览器
    浏览器收到内容之后看到字符串,在头部告诉浏览器是html文件,然后浏览器就按照html格式进行解析
    html里的css,pong,js等链接浏览器会重新发出请求,服务器将对应的文件再传给浏览器就完成了页面的传递

    __dirname nodejs 里的内置变量 代表当前的文件,该文件和static在同一级目录下
    path.join(__dirname, 'static' 自动生成一个static的绝对路径 (好处 window和mac 都能用)

    var pathObj = url.parse(req.url, true)
    req.url //解析出来要得到pathname即index.html
    var filePath = path.join(staticPath, pathObj.pathname)得到文件的绝对路径

    本地文件路径

    服务器代码

    var http=require('http') //创建服务器的模块
    var path=require('path')//处理URL统一格式写法
    var fs=require('fs') //用于读写文件
    var url=require('url') //解析URL获取其中的信息比如pathname
    
    function  staticRoot(staticPath,req,res){
    console.log(staticPath)
    console.log(req.url)
    var pathObj=url.parse(req.url,true)  //获取文件路径
    console.log(pathObj)
    
    if(pathnObj.pathname==='/'){
    pathObj.pathname+='index.html'
    }///默认打开端口服务器直接跳到index.html
    
    var filePath=path.join(staticPath,pathObj.pathname)
    //path.join(__dirname, 'static' 自动生成一个static的绝对路径 (好处 window和mac 都能用,不需要分别设置)
    
    
    fs.readFile(filePath,'binary',function(err,fileContent){
    if(err){
       console.log('404')
       res.writeHead(404,'not found')
       res.end(<h1>404 Not Found</h1>)
        }else{
          console.log('ok')
          res.writeHead(200,'OK')
          res.write(fileContent,'binary')
          res.end 
          }
      })
    //这部分主要就是如果路径错误就报错,对了就解析文件
    }
    
    console.log(path.join(__dirname,'static'))
    var server=http.createServer(function(req,res){
    staticRoot(path.join(__dirname,'static'),req,res)
    //__dirname nodejs 里的内置变量 代表当前的文件,该文件和static在同一级目录下
    //且该部分调用static目的是将代码条理化,看上去清晰
    
    
    })
    server.listen(8080)
    console.log('visit http://localhost:8080')
    
    

    设置路由

    如何让URL不止定位到一个文件,而是定位到任何的数据,或者mock数据与前端交互
    对于网页来说,域名后面的部分就是路由
    我们要完成的就是 根据路由的不同返回不同的数据

    当请求更复杂的时候,仅用url不够, 要进一步匹配pathname和query
    var pathObj = url.parse(req.url, true)

    var http = require('http')
    var fs = require('fs')
    var url = require('url')
    
    http.createServer(function(req, res){
    
      var pathObj = url.parse(req.url, true)
      console.log(pathObj)
    
      switch (pathObj.pathname) {//通过pathname来判断请求   
     case '/getWeather'://不同的请求
          var ret
          if(pathObj.query.city == 'beijing'){
            ret = {
              city: 'beijing',
              weather: '晴天'
            }
          }else{
            ret = {
              city: pathObj.query.city,
              weather: '不知道'
            }
          }
          res.end(JSON.stringify(ret))
          break;
        case '/user/123'://不同的请求
    
          res.end( fs.readFileSync(__dirname + '/static/user.tpl' ))
          break;
        default:
          res.end( fs.readFileSync(__dirname + '/static' + pathObj.pathname) )//这部分就是之前的静态服务器路径
      }
    }).listen(8080)
    
    

    上面这部分的缺陷是无法反应POST请求

    下面的服务器代码可以实现用POST和GET的方式传递数据的服务器,且设置了路由

    var http = require('http')
    var path = require('path')
    var fs = require('fs')
    var url = require('url')
    
    var routes = {
      '/a': function(req, res){
        res.end(JSON.stringify(req.query))
      },
    
      '/b': function(req, res){
        res.end('match /b')
      },
    
      '/a/c': function(req, res){
        res.end('match /a/c')
      },
    
      '/search': function(req, res){
        res.end('username='+req.body.username+',password='+req.body.password)
       
      },
       '/getWeather': function(req,res){
           var ret
           var pathObj = url.parse(req.url, true)//这句代码在好多作用域下都要使用,作用域之间隔离开,所以要分别声明
    
           if(pathObj.pathname==='hangzhou'){
               ret={
                   city:'hangzhou',
                   weather:'台风'
               }
           }else{
              ret={
               city:pathObj.query.city,
               weather:'不知道'}
           }
           res.end(JSON.stringify(ret))
       }      
    }
    

    上面这一部分是接口的集合,如果想要新添加或删减接口直接在这里进行设置端口
    req. query就是调用GET的数据
    req.body就是调用POST的数据

    var server = http.createServer(function(req, res){
      routePath(req, res)
    })
    
    server.listen(9000)
    console.log('visit http://localhost:9000' )
    console.log(path)
    

    这没什么好说的,就是服务器的开口,就只是调用了routePath函数,使得代码看上去条理

    function routePath(req, res){
      var pathObj = url.parse(req.url, true)
     
      var handleFn = routes[pathObj.pathname]
      if(handleFn){
        req.query = pathObj.query
    
        //参考 https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/
        // post json 解析
        var body = ''
        req.on('data', function(chunk){
          body += chunk
        }).on('end', function(){
          req.body = parseBody(body)
          handleFn(req, res)
        })
        //这部分内容主要是匹配routes里的POST请求,
        //调用parseBody将数据解析成对象
      }else {
        sampleRoot(path.resolve(__dirname, 'sample'), req, res)//即如果routes里没有对应的接口就进入sampleRoot函数
      }
    }
    
    function sampleRoot(samplePath, req, res){
      var pathObj = url.parse(req.url, true)
      var filePath = path.join(samplePath, pathObj.pathname)
      console.log(filePath)
      fs.readFile(filePath,'binary', function(err, content){
        if(err){
          res.writeHead('404', 'haha Not Found')//binary是采用2进制处理数据
          return res.end()
        }
    
        res.writeHead(200, 'Ok')
        res.write(content, 'binary')
        res.end()  
      })
    
    }
    

    这部分就是前面说的静态服务器,如果有正确对应的文件路径就执行,没有就报错404

    function parseBody(body){
      console.log(body)
      var obj = {}
      body.split('&').forEach(function(str){
        obj[str.split('=')[0]] = str.split('=')[1]
      })
      console.log(obj)
      return obj
    
    }
    

    body 得到的是 key=value的形式,然后包装成对象

    相关文章

      网友评论

        本文标题:如何搭建一个简单的静态服务器

        本文链接:https://www.haomeiwen.com/subject/gpaiiftx.html