进阶篇:静态服务器和服务器路由解析(15)
2019-07-04 本文已影响0人
饥人谷1904_陈俊锋
饥人谷进阶学习第 15 天
nodejs实现静态服务器
响应体:查看源代码看到的html
响应头:network里面的数据
原理 step0
// createServer函数内部(异步)会创建一个服务器
// 通过function回调函数作为对应参数来处理请求
// 浏览器访问服务器时底层封装成一个对象 req 用户请求的一些信息都在req对象里
// 需要返回用户的信息 res
var server = http.createServer(function(request, response){
setTimeout(function(){
// 设置响应头
response.setHeader('Content-Type','text/html; charset=utf-8')
// 状态码
response.writeHead(404, 'Not Found')
response.write('<html><head><meta charset="gbk" /></head>')
response.write('<body>')
response.write('<h1>你好</h1>')
response.write('</body>')
response.write('</html>')
response.end()
},2000);
})
console.log('open http://localhost:8080')
// listen方法真正启动服务器
server.listen(8080)
实现静态服务器 step1
// 模块
var http = require('http') //创建服务器模块
var path = require('path') //处理url(各系统url可能不同)
var fs = require('fs') //用于读写文件
var url = require('url') //自动解析url得到一些信息
function staticRoot(staticPath, req, res){
console.log(staticPath)
console.log(req.url)
var pathObj = url.parse(req.url, true)
console.log(pathObj)
if(pathObj.pathname === '/'){
pathObj.pathname += 'index.html'
}
var filePath = path.join(staticPath, pathObj.pathname)
// 同步方式去读文件
// var fileContent = fs.readFileSync(filePath,'binary')
// res.write(fileContent, 'binary')
// res.end()
// 异步方式
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()
}
})
}
var server = http.createServer(function(req, res){
staticRoot(path.join(__dirname, 'static'), req, res)
// __dirname是nodejs里的一个变量代表当前文件
})
server.listen(8080)
console.log('visit http://localhost:8080' )
服务器路由解析 step2
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)
}
}
// 程序入口
var server = http.createServer(function(req, res){
routePath(req, res)
})
server.listen(8080)
console.log('visit http://localhost:8080' )
function routePath(req, res){
// 解析url得到pathname路由
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 = ''
// 通过监听data和end事件来获取流内数据
req.on('data', function(chunk){
body += chunk // 拼接数据块
}).on('end', function(){
req.body = parseBody(body)
handleFn(req, res)
})
}else {
// 找不到路由请求当成静态文件处理
staticRoot(path.resolve(__dirname, 'static'), req, res)
}
}
function staticRoot(staticPath, req, res){
var pathObj = url.parse(req.url, true)
var filePath = path.join(staticPath, pathObj.pathname)
fs.readFile(filePath,'binary', function(err, content){
if(err){
res.writeHead('404', 'haha Not Found')
return res.end()
}
res.writeHead(200, 'Ok')
res.write(content, 'binary')
res.end()
})
}
// 解析数据
function parseBody(body){
console.log(body)
var obj = {}
body.split('&').forEach(function(str){
obj[str.split('=')[0]] = str.split('=')[1]
})
return obj
}