今天的内容我们聊一聊 HTTP 从客户端和服务端是如何「协作」通信的,我把这个过程比作是小卖部与生产商之间的协作,他们有很多异曲同工之处。
在北方的农村,为满足了人们的日常需求,各村都会设立自己的小卖部,小卖部的供货渠道主要依靠生产厂商阶段性送货。生产厂商掌握着资源,小卖部不断地获取资源。
在 HTTP 协议中,「小卖部」扮演的角色类似于 UA(User Agent),UA 其实就是我们常说的客户端,比如浏览器,app,它的作用就是可以发起一个请求(request)。「生产商」扮演的角色是服务端的角色,它为客户端提供资源(response)。当服务端接收到客户端的请求后,会给出一个响应作为回答。总之,HTTP 协议需要一个客户端与一个服务端。
在很久以前,由于不发达,小卖部与生产厂商是无法建立联系的,他们只能双方约定一个送货时间,比如每周一送一次货。这样,小卖部可能会出现断货,因为他们约定只在周一进行供货。后来有了电话,便开始使用电话沟通。直到今天,他们开始使用微信沟通。一天张三向生产厂商发了一条消息:”我需要:方便面10箱,火腿1箱,面包10个,牛奶20箱“;李四向生产厂商发了一条消息:”我需要:火腿2箱,面包1个,牛奶2箱“ ....... 生产厂商每天要处理几百条类似这样的消息。生产厂商不得不多雇几个人来处理这些事情,安排发货。后来有个聪明的家伙王经理向老板说:”我们给各个小卖部制定一个标准吧,约定他们只能按照我们约定的消息来发送供货需求,否则我们不提供服务。这样我们使用电脑来处理这些订单,无需人为干预,可以节约成本,而且可以提升效率。“。老板听后,非常开心,并给王经理加薪作为奖励。
王经理说的「标准」就是 HTTP协议,双方约定通信内容要按照统一的格式。这个「格式」就是 HTTP 协议规定的报文格式。王经理想了想,生产厂商有非常多的资源,必须要通过一个规则来标识货物,比如牛奶、饼干、面包这些该如何标识,而且一旦生产厂商不能提供货物需要给小卖部一个明确的答复。由于王经理以前干过程序员,然后它直接借鉴了 HTTP 协议的设计。他画了一个草图:
当小卖部需要货的时候,直接发起一个请求即可,比如:小王家向北京地区的生产厂商发起了 buy://174.162.66.8:666/食品类?方便面=2箱&火腿=20根,buy 表示购买,174.162.66.8 代表国内的生产厂商,666 表示北京地区的生产厂商,食品类?方便面=2箱&火腿=20根,表示到食品仓库中找方便面2箱,火腿20根。
HTTP 在发起请求的时候,它会按照协议的规定组合成一条一条文本内容,通过 TCP 来传送到 server 端。当 server 端开启一个 HTTP 服务后,它便会一直监听客户端的请求。整个请求过程,我画了一张图:
在 第3天:HTTP 之客户端与服务端 介绍了 HTTP 客户端和服务端的使用。我们一起回顾一下客户端代码:
// 构建 request 对象所需要的参数
const options = {
// 请求地址 ip
host: '127.0.0.1',
// 端口号
port: 8888,
// 方法
method: 'GET',
// 请求的路径
path: '/api/fe/list',
protocol: 'http:',
// 超时时间设置 1秒
timeout: 1000
}
const req = http.request(options, function (res) {
res.setEncoding('utf8');
// 响应数据
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
});
服务端代码如下:
const http = require('http');
// 创建一个 HTTP server
const server = new http.Server();
/**
* request 事件,当客户端发起请求后会响应这个事件
* req:请求对象
* res:响应对象
* */
server.on('request', function(req, res) {
// 处理请求的 path 为 /api/fe/list
res.writeHead(200, {
"Content-type" : "application/json"
});
let data = {
title: "前端小课",
des: "内容由素燕公众号发布"
};
// 最终数据需要转换成 json 字符串
res.write(JSON.stringify(data));
res.end();
});
// 监听 8888 端口
server.listen(9999, function() {
console.log('Server run in: http://127.0.0.1:9999');
});
总结
今天的打卡指令:
1. HTTP 协议使用 TCP 传输的内容是什么?json、文本、html,还是其它什么?
2.你使用 HTTP header 干过什么?
3.HTTP中的 cookie 是如何传输的?