4. Node 之 http 模块

169 阅读5分钟

一、http 模块描述及作用

1. 什么是 http 模块

回顾: 什么是 客户端、什么是服务器 ? 在网络节点中,负责消费资源的电脑,叫做客户端;负责对外提供网络资源的电脑,叫做服务器。

http 模块是 Node.js 官方提供的,用来创建 web 服务器的模块。通过 http 模块提供的 http.createServer() 方法, 就能方便的把一台普通的 web 服务器,从而变成对外 提供 web 资源服务。

如果希望使用 http 模块来创建 Web 服务器, 则需要先导入它:

const http = require('http')

2. http 模块的作用

服务器和普通电脑的区别在于, 服务器上安装了 Web 服务器软件,例如:IIS、Apache 等。通过安装这些服务器软件,就能把一台普通的电脑变成一台 Web 服务器。

在 Node.js 中,我们不需要使用 IIS、Apache 等这些第三方 Web 服务器软件。因为我们可以基于 Node.js 提供的 http 模块, 通过几行简单的代码, 就能轻松的手写一个服务器软件,从而对外提供 Web 服务

二、服务器相关概念

1. IP 地址

IP 地址 就是 互联网上每台计算机的唯一地址,因些 IP 地址具有唯一性。如果把“ 个人 电脑 ” 比作 ‘ 一台电脑 ’,那么, “ IP 地址 ”就相当于 “ 电话号码 ”,只有在知道对方 IP 地址 的前提下,才能与对应的电脑之间进行数据通信。

IP地址的格式: 通常用 “ 点分十进制 ”表示成 ( a.b.c.d )的形式,其中,a, b , c, d 每个都是 0 ~ 255 之间的十进制整数。例如: 用点分十进制表示的 IP 地址(180.101.49.11)

注意:

  1. 互联中的每台 Web 服务器,都有自己的 IP 地址, 例如: 大家可以在 Window 的终端中运行ping www.baidu.com命令,就可以查看到百度服务器的 IP 地址。

  2. 在开发期间,自己的电脑就是一台服务器,也是一个客户端。为了方便测试,可以在自己的浏览器中输入 127.0.0.1 这个 IP地址,就能把自己的电脑当作一台服务器访问了。

2. 域名 和 域名服务器

虽然 IP 地址能够标记网络上的计算机,但 IP 地址是一长串数字,不直观, 而且不便于记忆。于是人们又发明了另一套字符型的 地址方法, 即所谓的域名(Domain Name) 地址。例如 www.baidu.com

IP地址 和域名 是一一对应的关系,这份关系存放在一种叫做 域名服务器(DNS, Domain name server )的电脑中,使用者只需通过好记的域名访问对应的服务器即可,对应的转换工作由域名服务器实现。因此, 域名服务器就是提供 IP 地址 和域名 之间的转换器的服务器。

注意:

  1. 单纯的使用 IP 地址,互联中的电脑也能够正常工作,但是有了域名的加持, 能让互联网的世界变得更加方便。

  2. 在开发测试期间, 127. 0.0.1 对应的域名是 localhost。它们都代表我们自己的这台电脑,在使用效果上没有任何区别。

3. 端口号

计算机中的端口号,就好像现实生活中的门牌号,外卖小哥哥可以在整栋大楼众多的房间中,准确的把外卖送到你的手中。

同样的道理,在一台电脑中,可以运行成百上千个 Web 服务器,每个 Web 服务器 都对应一个唯一的端口号,客户端发送过来的网络请求,通过不同的端口号,可以准确地交给对应的 Web 服务器进行处理。

image.png

三、http 模块创建 web 服务器

1. 创建 Web 服务器 步骤

创建 Web 服务器 步骤 需要 以下 4 步:

  1. 导入 http 模块
const http = require("http");
  1. 创建 Web 服务器实例
const server = http.createServer();
  1. 为 服务器 实例绑定 request 事件,监听客户端需求。
server.on('request', (req, res) => {
    console.log('发送命令')
})
  1. 调用服务器实例的 .listen(), 便可启动当前的 Web 服务器实例。

    注意项:listen 第一个参数为 端口号,默认为 80,如果为默认的端口号,可以不用在域名后面添加 80 端口号。

// 默认的端口号
server.listen(80, () => {
    console.log('运行中 http://127.0.0.1')
})


// 不是默认的端口号
server.listen(8080, () => {
    console.log('运行中 http://127.0.0.1:8080')
})

2. req 请求对象

只要服务器接收了客户端的请求,就会调用通过 server.on() 为服务器绑定的 request 事件处理函数。如果在事件处理函数中,访问与客户端相关的数据或属性,可以用如下的方式:

server.on('request', (req, res) => {
    let url = req.url;
    let method = req.method;
    let str = `地址是 ${url}, 请求方式是 ${method}`
    console.log(str)
})

3. res 响应对应

在服务器的 request 事件处理函数中,如果想访问与服务器相关的数据或属性,可以使用如下的方式:

server.on('request', (req, res) => {
    let str = `地址是 ${req.url}, 请求方式是 ${req.method}`
    res.end(str)
})

4. 解决 中文乱码 问题

当调用 res.end() 方法时,向客户端发送中文内容的时候,会出现乱码问题,此时,需要手动设置 内容的编码格式

server.on('request', (req, res) => {
    // 发送的内容包含中文
    let str = `地址是 ${req.url}, 请求方式是 ${req.method}`
    // 为了防止中文显示乱码的问题,需要设置响应头 Content-Type 的值 为 text/html;charset = utf-8
    res.setHeader('Content-Type', 'text/html;charset=utf-8')
    // 把包含中文的内容,响应给客户端
    res.end(str)
})

5. 动态响应内容

根据不同的 url 响应不同的 html 内容

const http = require("http");
const server = http.createServer();

server.on("request", (req, res) => {
  let content = "<h2>404 No found</h2>";
  let url = req.url;
  console.log(url, '_____________')
  if(['/', '/index.html'].includes(url)) {
    content = "<h2>首页</h2>"
  } else if(url === '/about.html') {
    content = '<h2>关于页面</h2>'
  } 
  res.setHeader('Content-Type', 'text/html;charset=utf-8')

  res.end(content)
});

server.listen(8080, () => {
    console.log(`runing http://127.0.0.1`)
})

四、http 应用

需求:把客户端访问的左侧 clock 里面的文件,内容返回给客户端

image.png image.png

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

const server = http.createServer();

server.on('request', (req, res) => {
    let url = req.url;
    let fPath = '';
    if(url === '/') {
        // 如果请求的路径为 / , 则手动指定文件的存放路径
        fPath = path.join(__dirname, '/clock/index.html')
    } else {
        // 如果请求的路径不为 /, 则动态拼接成文件的存放路径
        fPath = path.join(__dirname, '/clock', url)
    }

    fs.readFile(fPath, 'utf8', (err, dataStr) => {
        if(err) return res.end('404 no Found')

        res.end(dataStr)
    })
})

server.listen(80, () => {
    console.log('runing http://127.0.0.1')
})