banner
banner
banner
NEWS LETTER

搭建最简单的服务器

Scroll down

搭建简单的服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import http from "http"
// 创建server服务器对象
const server = http.createServer()
// 监听对当前服务器对象的请求
server.on('request', (req,res) => {
// req: 请求数据都会放在请求对象里
// res: 能够做出响应对象
// 当服务器被请求时,会触发请求事件,并传入请求对象和响应对象
// 设置响应头
res.setHeader('Content-Type','text/html;charset=utf-8;')

// 根据路径信息显示不同页面
if(req.url == "/") {
res.end('首页')
}else if (req.url == "/gnxw"){
res.end('国内新闻首页')
}else if (req.url == "/ylxw"){
res.end('娱乐新闻首页')
}else {
res.end("<h1>404页面查找不到!</h1>")
}
})

// 启动服务器
server.listen(端口号,回调函数)

优化服务器性能封装服务器的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class ServerApp {
constructor() {
// 创建server服务器对象
this.server = http.createServer()
// 创建请求事件的空对象
this.reqEvent = {}
// 暴露目录名:可以让人修改,但实际上不管怎么改都是使用static这个目录,做到混淆他人获取信息
this.staticPath = "/static"
// 监听对当前服务器对象的请求
this.server.on('request', (req,res) => {
// 解析路径
let pathObj = path.parse(req.url)
if( pathObj.dir in this.reqEvent) {
// 将渲染函数添加到响应对象中
res.render = render
res.setHeader("Content-Type", "text/html;charset=UTF-8")
req.pathObj = pathObj
this.reqEvent[pathObj.dir](req,res)
} else if (pathObj.dir == this.staticPath){
// 读取静态目录
res.setHeader("Content-Type", this.getContentType(pathObj.ext))
let rs = fs.createReadStream('./static/' + pathObj.base)
rs.pipe(res)
} else {
res.setHeader("Content-Type", "text/html;charset=UTF-8")
res.end('<h1>404页面找不到!</h1>')
}
})
}
// 封装监听请求
on (url, fn) {
this.reqEvent[url] = fn
}
// 服务器启动
run (port,callback) {
this.server.listen(port,callback)
}
// 封装对应什么后缀名返回什么头响应模式
getContentType(extName) {
switch(extName) {
case ".jpg":
return "image/jpeg"
case ".html":
return "text/html;charset=utf-8"
case ".js":
return "text/javascript;charset=utf-8"
case ".json":
return "text/json;charset=utf-8"
case ".gif":
return "image/gif"
case ".css":
return "text/css"
}
}
}
default ServerApp

根据数据与模板动态生成页面

  1. 根据规则去解析链接,并且获取ID或者索引值

    • let index = req.pathObj.base
    • 请求路径: localhost:3000/movices/1
  2. 根据索引获取数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    let movices = [{
    name: '长空之王',
    desc: '试飞员的故事',
    author: '胡军、王一博',
    list: ['a','b','c']
    },{
    name: '热烈',
    desc: '由街舞引申的关于梦想和青春的故事',
    author: '王一博'
    }]
    let pageData = movices[index]
  3. 根据模板渲染页面

    • res.render(movices[index], ‘./template/index.html’)
  4. 底层需要实现渲染函数,通过正则匹配,找到需要修改的地方进行一一修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function render(options, path) {
    fs.readFile(path,{encoding: "utf-8", flag: "r"},(err,data) => {
    // 这里使用箭头函数,使this指向调用的res
    if(err){
    console.log(err)
    }else {
    console.log(data)
    let reg = /\{\{(.*?)\}\}/igs
    let result;
    while(result = reg.exec(data)) {
    // 去除key两边的空白字符,并拿到key
    let strKey = result[1].trim()
    let strValue = options[strKey]
    data = data.replace(result[0],strValue)
    }
    this.end(data)
    }
    })
    }

列表的动态渲染

  1. 在html页面定义列表循环的标记

    1
    2
    3
    4
    5
    <ul>
    {%for {list} %}
    <li>{{item}}</li>
    {%endfor%}
    </ul>
  2. 正则匹配标记

    • let listreg = /\{\%for \{(.*?)\} \%\}(.*?)\{\%endfor\%\}/igs
    • 从中匹配到两个组
      • 第一个组匹配出变量的key值
      • 第二哥组匹配出需要生成的每一项的内容
  3. 匹配替换每一项的内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    while(listResult = listreg.exec(data)) {
    let list = listResult[1].trim()
    // 通过key值获取数据内容
    let listValue = options[list]
    let listStr = ''
    listValue.forEach((item,index) => {
    // 替换每一项内容的变量
    console.log(item)
    listStr = listStr + replaceVAr(listResult[2], {"item":item})
    })
    data = data.replace(listResult[0],listStr)
    }
  4. 通过eval函数,将字符串的表达式计算出来

    • let strValue = eval(‘options.’ + strKey)

正则路由的设定

  • 要求:可以根据自己设定的正则匹配路径来执行想应的函数来响应用户的内容
  1. 设定正则的匹配路径和响应的执行函数

    1
    2
    3
    serverRqquest.on('^/$', (req, res) => {
    res.end("<h1>首页</h1><img src='./abc/bg-1.jpg'>")
    })
  2. 获取正则路径创建正则对象

    • let reg = new RegExp(regStr, ‘igs’)
  3. 匹配路径,并调用相对应的函数

    1
    2
    3
    4
    5
    if(reg.test(req.url)) {
    this.reqEvent[key](req, res)
    resState = true
    break
    }
  4. 判断是否正则路径响应过,如果响应过,将不在响应,会报错

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if(!resState) {
    if (pathObj.dir == this.staticPath){// 静态目录
    res.setHeader("Content-Type", this.getContentType(pathObj.ext))
    let rs = fs.createReadStream('./static/' + pathObj.base)
    rs.pipe(res)
    } else {
    res.setHeader("Content-Type", "text/html;charset=UTF-8")
    res.end('<h1>404页面找不到!</h1>')
    }
    }
其他文章
cover
梳理框架流程
  • 24/10/31
  • 17:15
  • Node
cover
爬虫总结
  • 24/10/31
  • 17:15
  • Node
目录导航 置顶
  1. 1. 搭建简单的服务器
  2. 2. 优化服务器性能封装服务器的方法
  3. 3. 根据数据与模板动态生成页面
  4. 4. 列表的动态渲染
  5. 5. 正则路由的设定
请输入关键词进行搜索