一、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)
注意:
-
互联中的每台 Web 服务器,都有自己的 IP 地址, 例如: 大家可以在 Window 的终端中运行
ping www.baidu.com命令,就可以查看到百度服务器的 IP 地址。 -
在开发期间,自己的电脑就是一台服务器,也是一个客户端。为了方便测试,可以在自己的浏览器中输入
127.0.0.1这个 IP地址,就能把自己的电脑当作一台服务器访问了。
2. 域名 和 域名服务器
虽然 IP 地址能够标记网络上的计算机,但 IP 地址是一长串数字,不直观, 而且不便于记忆。于是人们又发明了另一套字符型的 地址方法, 即所谓的域名(Domain Name) 地址。例如 www.baidu.com
IP地址 和域名 是一一对应的关系,这份关系存放在一种叫做 域名服务器(DNS, Domain name server )的电脑中,使用者只需通过好记的域名访问对应的服务器即可,对应的转换工作由域名服务器实现。因此, 域名服务器就是提供 IP 地址 和域名 之间的转换器的服务器。
注意:
-
单纯的使用 IP 地址,互联中的电脑也能够正常工作,但是有了域名的加持, 能让互联网的世界变得更加方便。
-
在开发测试期间, 127. 0.0.1 对应的域名是 localhost。它们都代表我们自己的这台电脑,在使用效果上没有任何区别。
3. 端口号
计算机中的端口号,就好像现实生活中的门牌号,外卖小哥哥可以在整栋大楼众多的房间中,准确的把外卖送到你的手中。
同样的道理,在一台电脑中,可以运行成百上千个 Web 服务器,每个 Web 服务器 都对应一个唯一的端口号,客户端发送过来的网络请求,通过不同的端口号,可以准确地交给对应的 Web 服务器进行处理。
三、http 模块创建 web 服务器
1. 创建 Web 服务器 步骤
创建 Web 服务器 步骤 需要 以下 4 步:
- 导入
http模块
const http = require("http");
- 创建
Web服务器实例
const server = http.createServer();
- 为 服务器 实例绑定
request事件,监听客户端需求。
server.on('request', (req, res) => {
console.log('发送命令')
})
-
调用服务器实例的 .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 里面的文件,内容返回给客户端
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')
})