企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[http协议入门:https://www.ruanyifeng.com/blog/2016/08/http.html]([https://www.ruanyifeng.com/blog/2016/08/http.html](https://www.ruanyifeng.com/blog/2016/08/http.html)) ## HTTP工作原理 HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。 1. **客户端连接到Web服务器** 一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接 2. **发送HTTP请求** 通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成 3. **服务器接受请求并返回HTTP响应** Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。 4. **释放连接 TCP连接** 若connection 模式为close,则服务器主动关闭[TCP连接](https://www.jianshu.com/p/ef892323e68f),客户端被动关闭连接,释放[TCP连接](https://www.jianshu.com/p/ef892323e68f);若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求; 5. **客户端浏览器解析HTML内容** 客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。 ## HTTP响应头的 Content-Type字段 头信息必须是ASCII码,数据部分可以是任何格式。因此,服务器回应的时候,必须告诉客户端,数据是什么格式的,这就是Content-Type字段的作用。如`text/html`,`text/css`,`application/javascript`等 客户端请求的时候,可以使用Accept字段声明自己可以接受哪些数据格式`Accept:*/*`; ## Content-Encoding字段 由于发送的数据可以是任何格式,因此可以把数据压缩后再发送。Content-Encoding字段说明数据的压缩方法 ``` Content-Encoding: gzip Content-Encoding: compress Content-Encoding: deflate ``` 客户端在请求时,用Accept-Encoding字段说明自己可以接受哪些压缩方法。`Accept-Encoding: gizp, deflate;` ## 持久连接 HTTP1.1引入了持久连接,即TCP连接默认不关闭,可以被多个请求复用,不用声明`Connection:keep-alive`. 客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过规范的做法是,客户端在最后一个请求时,发送`Connection: close`,明确要求服务器关闭TCP连接 ## 管道机制 1.1 版还引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率 举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。 ## Content-Length字段 一个TCP连接现在可以传送多个回应,势必就要有一种机制,区分数据包是属于哪一个回应的。这就是`Content-length`字段的作用,声明本次回应的数据长度。 ``` Content-Length: 3495 ``` 上面代码告诉浏览器,本次回应的长度是3495个字节,后面的字节就属于下一个回应了。 在1.0版中,`Content-Length`字段不是必需的,因为浏览器发现服务器关闭了TCP连接,就表明收到的数据包已经全了。 ## 分块传输编码 使用`Content-Length`字段的前提条件是,服务器发送回应之前,必须知道回应的数据长度。 对于一些很耗时的动态操作来说,这意味着,服务器要等到所有操作完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用"流模式"(stream)取代"缓存模式"(buffer)。 因此,1.1版规定可以不使用`Content-Length`字段,而使用"分块传输编码"(chunked transfer encoding)。只要请求或回应的头信息有`Transfer-Encoding`字段,就表明回应将由数量未定的数据块组成。 每个非空的数据块之前,会有一个16进制的数值,表示这个块的长度。最后是一个大小为0的块,就表示本次回应的数据发送完了