新手的 http 开发入门理解, 十分粗浅不足, 请多指教
tcp 注意事项
server
- createServer
- listen host port
- (ip1)0.0.0.0 与 (ip2)localhost, (ip3)127.0.0.1 的区别: ip1 局域网和本机都能访问, ip2, ip3 只能本机访问, ip2 是 ip3 的别名
client
- createConnection
- connect 事件
- data 事件
http 注意事项
- http 是一个文本协议基于 tcp, 也就是说上面 tcp 连接建立后开始发送 http 文本
- 分为 请求行, 请求头, 请求体, req, res 注要注意力就在这上面
- server 上 req 是一个可读 stream, res 是一个可写 stream
server-req
- req 主要用到的属性有 method, header, url
- method 获取到的字符串全是大写的
- header 是个字典, key 都是小写
- url 包含 host 后的所有字符, ‘/’ 开头
- 可以用 url.parse 解析 req.url 获取 url 对象, url 对象中, pathname 是路由, query 是 get 请求的参数, 可以用 querystring 解析成对象
//http://wangding:[email protected]:8080/a/b/c?age=20&gender=M#/d/e/f
Url {
protocol: 'http:',
slashes: true,
auth: 'wangding:123',
host: 'www.baidu.com:8080',
port: '8080',
hostname: 'www.baidu.com',
hash: '#/d/e/f',
search: '?age=20&gender=M',
query: 'age=20&gender=M',
pathname: '/a/b/c',
path: '/a/b/c?age=20&gender=M',
href:
'http://wangding:[email protected]:8080/a/b/c?age=20&gender=M#/d/e/f'
}
- req 可用 data 事件获取请求体, 根据 header 中 content-type 判断编码格式
- 关于请求体中上传文件的解析太麻烦, 建议还是用现成的库
server-res
- res 主要用到 api 有 statusCode, setHeader, writeHeader
- 主要就是设置响应行, 响应头的 api, writeHeader 后 seHeader 无效
- res 是一个 可写 stream, 所以写入大文件的时候可以用 pipe, 省时省力省心, 简直爱死 pipe, 最优美的 api 没有之一
client-req
- req 的使用方法跟 server 中 res 类似
- 可写 stream 写入文件也可以用 pipe
- 文档上写调用 end 方法才会最终发送请求, 不太准确, 实际是开始向 req stream 中写入数据的时候就已经开始连接了
client-res
- res 的使用方法跟 server 中 req 类似
- 可读 stream
总结
- 面试中经常问从浏览器中输入网址回车之后到显示网页发生了什么事情, 通过上面的梳理我们可以很清晰的说出来
- 输入网址后, 询问 DNS 获得 ip 地址
- 通过 ip port 建立 tcp 连接, 三次握手…, 获得 socket 对象
- 客户端按照 请求行, 请求头, 请求体 的格式通过 socket 发送文本
- 服务端按照 请求行, 请求头, 请求体 的格式解析 获取里面的数据
- 执行业务逻辑
- 服务端按照 响应行, 响应头, 响应体 的格式通过 socket 发送数据, 里面可以是 json, html, 文本, 文件…
- 客户端按照 响应行, 响应头, 响应体 的格式解析 获取里面的数据
- 开始渲染
- 由此可见为什么说 http 是建立在 tcp 之上, 实际上就是通过 socket 发送格式化好的文本
- 我们可以自己根据协议解析 socket 发送出来的数据, 构建 req, res 对象, 然后把 res 按 http 协议格式化好通过 socket 发送, 于是乎就实现了一个 http 服务器
- 后端框架帮我们做的事情是, 用一种规范方便的方式让我们拿到 http 中的数据, 解耦业务逻辑和 http 协议解析, 发送
另外我建了一个 百天全栈计划, 欢迎大家加群 542160608, 互相打卡监督