为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Html/CSS

搭建的基本结构

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)得到文件的绝对路径

本地文件路径

webp

服务器代码

var http=require('http') //创建服务器的模块var path=require('path')//处理URL统一格式写法var fs=require('fs') //用于读写文件var url=require('url') //解析URL获取其中的信息比如pathnamefunction  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.htmlvar 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

}



作者:clumsy钧
链接:https://www.jianshu.com/p/26beb4c90840


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消