欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

程序员文章站 2022-07-10 20:20:02
...

一、静态服务器

能够根据需要请求的文件,原封不动的将服务器磁盘中的数据直接返回给到浏览器。

具体事例:

let http = require('http');							// 引入http模块
let path = require('path')							// 引入path模块
let fs = require('fs')								// 引入文件模块


let server = http.createServer()					// 创建server对象
server.on('request', function(req, res) {			// 监听客户端发送过来的请求,req请求对象包含了请求的相关的信息,res对象用于响应内容,可以通过这个对象帮助我们快速实现HTTP响应
    let urlObj = path.parse(req.url)				// 解析路径,注意这里的路径是‘\’开头的
    if(req.url == "/") {							// 识别请求的路径,在这里是主页
        res.setHeader("content-type", "text/html; charset = utf-8")		// 告诉浏览器返回数据的编码,以免乱码
        res.end('这里是主页')						// 把数据响应给浏览器
    }else if(urlObj.dir == '/static') {				// 判断是否请求静态资源
        res.setHeader("content-type", getContentType(urlObj.ext))		// 设置响应头(返回数据的格式)
        let rs = fs.createReadStream('./static/' + urlObj.base)			// 读取静态文件信息
        rs.pipe(res)								// 通过管道把数据响应给浏览器
    }else {											// 其他情况
        res.setHeader("content-type", "text/html; charset = utf-8")		// 设置响应头
        res.end("404 页面找不到")					// 返回数据
    }
    
})
​
server.listen(80, function() {						// 启动服务器,监听服务端口
    console.log("服务已启动:http:127.0.0.1")
})function getContentType(extName) {					// 此函数目的是:根据请求的资源返回该资源的MIME格式
    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"
    }
}

不过上面有一点小缺陷,在于在 路径判断里面的if与else很多逻辑混乱,下面就来改进他

// main.js文件
const http = require('http');
const url = require('url');
const fs = require('fs');

class httpApp {											// 发布者
  constructor() {			
    this.server = http.createServer();					// 开启http服务
    this.requestList = {};								// 记录订阅者
    this.handler();										// 注册事件
  }

  on(requestWay, requestFn) {							// 订阅者订阅发布者
    this.requestList[requestWay] = requestFn;
  }
  
  handler() {
    this.server.on('request', (request, response) => {	// 注册服务器监听request事件
      let urlObj = url.parse(request.url);				// 解析请求的url
      let regexp = /(.*?)(\..*?)?$/;					// 字符串匹配
      regexp.exec(urlObj.pathname)		

      if(urlObj.pathname in this.requestList) {			// 检查url是否在订阅目录内
        this.requestList[urlObj.pathname](request, response)			// 在就执行函数
      }else if(RegExp.$1.indexOf('/static') >= 0 ) {	// 判断是否为静态资源
        let path = '.' + RegExp.$1 + RegExp.$2;			// 得到静态资源的目录结构
        response.setHeader('Content-type', getContentType(RegExp.$2)) 	// 设置响应头
        let rs = fs.createReadStream(path);				// 读取静态文件
        rs.pipe(response)								// 把静态文件传出去
      }else {											// 其他不存在请求
        response.setHeader('Content-type', 'text/plain; charset= utf-8')
        response.end('路径不存在');
      }
    })
    
  }
  run(port, fn) {
    this.server.listen(port, fn)						// 启动服务器
  }
}

function getContentType(extName) {					// 此函数目的是:根据请求的资源返回该资源的MIME格式
    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"
    }
}

module.exports = {										// 导出模块
  httpApp
}







---------------------------------------------------------------------------------------------------------------
// index.js文件
const { httpApp } = require('./main');

let instanceHttp = new httpApp();						// 实例化自封装的http模块

instanceHttp.on('/', (req, res) => {					// 注册事件,订阅者订阅发布者
  console.log(req.url);
  console.log(1);
  res.setHeader('Content-type', 'text/plain; charset= utf-8');
  res.end('这是主页')
})

instanceHttp.on('/login', (req, res) => {				// 注册事件,订阅者订阅发布者
  console.log(req.url);
  console.log(2);
  res.setHeader('Content-type', 'text/plain; charset= utf-8');
  res.end('这是登陆界面')
})

instanceHttp.on('/category', (req, res) => {			// 注册事件,订阅者订阅发布者
  console.log(req.url);
  console.log(3);
  res.setHeader('Content-type', 'text/plain; charset= utf-8');
  res.end('这是分类')
})

instanceHttp.run(80, () => {							// 启动服务
  console.log('服务已启动');
  
})


二、动态服务器

index.js文件

const { httpApp } = require('./main');
const { render } = require('./utils');


let instanceHttp = new httpApp();

instanceHttp.on('/', (req, res) => {
  res.setHeader('Content-type', 'text/plain; charset= utf-8');
  res.end('这是主页')
})
instanceHttp.on('/login', (req, res) => {
  res.setHeader('Content-type', 'text/plain; charset= utf-8');
  res.end('这是登陆界面')
})
instanceHttp.on('/category', (req, res) => {
  res.setHeader('Content-type', 'text/plain; charset= utf-8');
  res.end('这是分类')
})
instanceHttp.on('/profile', async (req, res) => {
  res.setHeader('Content-type', 'text/html; charset= utf-8');
  res.end(await render(person, './index.html'))			// 获取动态的页面
})

let person = {
  name: '李老板',
  gender: '男',
  age: 30
}


instanceHttp.run(80, () => {
  console.log('服务已启动');
  
})


index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div>
    <h2>{{ name }}</h2>
    <h2>{{ age }}</h2>
    <h2>{{ gender }}</h2>
  </div>
</body>
</html>

main.js文件

const http = require('http');
const url = require('url');
const fs = require('fs');

class httpApp {
  constructor() {
    this.server = http.createServer();
    this.requestList = {};
    this.handler();
  }

  on(requestWay, requestFn) {
    this.requestList[requestWay] = requestFn;
  }
  
  handler() {
    this.server.on('request', (request, response) => {
      let urlObj = url.parse(request.url);
      let regexp = /(.*?)(\..*?)?$/;
      regexp.exec(urlObj.pathname)

      if(RegExp.$1 in this.requestList) {
        this.requestList[RegExp.$1](request, response)
      }else if(RegExp.$1.indexOf('/static') >= 0 ) {
        let path = '.' + RegExp.$1 + RegExp.$2;
        response.setHeader('Content-type', getContentType(RegExp.$2)) 
        let rs = fs.createReadStream(path);
        rs.pipe(response)
      }else {
        response.setHeader('Content-type', 'text/plain; charset= utf-8')
        response.end('路径不存在');
      }
    })
    
  }
  run(port, fn) {
    this.server.listen(port, fn)
  }
}

function getContentType(extName) {					// 此函数目的是:根据请求的资源返回该资源的MIME格式
  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"
  }
}

module.exports = {
  httpApp
}

utils.js文件

const fs = require('fs');

function render(options, target) {					// 渲染页面的函数
  return new Promise(async (resolve, reject) => {
    let finalData = '';
    let rs = await fs.createReadStream(target, {
      encoding: 'utf-8',
      flags: 'r'
    });

    rs.on('data', (data) => {
      let regexp = /\{\{(.*?)\}\}/igs;
      finalData = data;
      let res = [];
      while(res = regexp.exec(data)) {
        if(res[1].trim() in options) {
          finalData = finalData.replace(res[0], options[res[1].trim()])
        }else {
          console.log('数据错误');
        }
      }
      resolve(finalData);
    })

    rs.on('close', () => {
      console.log('关闭');
      
    })

    rs.on('error', () => {
      reject('错误')
    })
    })
}

module.exports = {
  render
}

三、npm的上传包

1. 创建文件夹

把需要上传的文件放在刚创建的文件夹内

2. npm包的初始化

在控制台输入:

npm init

3. npm包信息的设置

{
  "name": "packageName",					// npm包的名字
  "version": "0.1.0",						// 包的版本
  "description": "将原生的fs模块进行promise封装,可以快速的使用async_await模式",										// 包的描述
  "main": "index.js",						// 包的入口文件(路径)
  // "test commed" 为测试命令
  // "git repository" 为git的包
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [								// 包的关键词
    "promise封装"
  ],
  "author": "李老板",						// 作者名
  "license": "ISC"							// 许可证
}

4. 注册NPM官网账号并邮箱验证

点击这里

5. 本机登陆NPM

npm login

输入用户名、邮箱与密码即可

6. 发布NPM包

npm publish

四、在公网上部署服务器

需要使用花生壳,它可以将私网的IP与端口和公网的IP与端口映射起来不过内网的电脑必须一直在线,不然链接会掉

1、账号的注册并实名认证

2、在控制台点击花生壳

里面有个免费版本的,再点进去
Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)
然后会跳出来一个购买免费服务,不用说买它
进入会出现以下界面,点击加号
Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

3、添加

出现以下界面,并依次填写
Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

4、下载花生壳

点击

5、在花生壳软件里面进行其他操作

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

五、MySQL的安装与使用

1、同意协议

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

2、选择Server only

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

3、过程可能需要安装C的包(因为环境需要),一路确定即可

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

4、下一步

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

5、选择Standard

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

6、下一步

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

7、端口可以修改,但没有必要

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

8、选择Use legacy

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

9、设置密码

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

10、下一步

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

11、执行

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)

12、在开始里面找到MySQL文件

Nodejs的学习Ⅳ(静态与动态服务器的简单搭建、npm的上传包、在公网上部署服务器、MySQL的安装)
点击Command Line测试MySQL,输入密码即可,不过也可以安装navicat工具,来可视化操作数据库navicat的安装一路下一步即可

本文只用于个人学习与记录

相关标签: NodeJs node