计算机网络 --- HTTP协议
HTTP
- 它是基于TCP协议的应用层传输协议,简单来说就是客户端和服务端进行数据传输的一种规则
- HTTP 是一种无状态 (stateless) 协议, HTTP 协议本身不会对发送过的请求和相应的通信状态进行
持久化处理。这样做的目的是为了保持HTTP协议的简单性,从而能够快速处理大量的事务, 提高效
率。- 然而,在许多应用场景中,我们需要保持用户登录的状态或记录用户购物车中的商品。由于 HTTP
是无状态协议,所以必须引入一些技术来记录管理状态,例如 Cookie
HTTP请求的过程
- 对http://www.baidu.com这个网址进行DNS域名解析,得到对应的IP地址
- 根据这个IP,找到对应的服务器,发起TCP的三次握手
- 建立TCP连接后发起HTTP请求
- 服务器响应HTTP请求,浏览器得到html代码
- 浏览器解析html代码,并请求html代码中的资源(如js、css图片等)(先得到html代码,才能去找这些资源)
- 浏览器对页面进行渲染呈现给用户
HTTP 结构
GET或POST 请求的URL路径(一般是去掉域名的路径) HTTP协议版本号\r\n
字段1名: 字段1值\r\n
字段2名: 字段2值\r\n
......
字段n名 : 字段n值\r\n
\r\n
http协议包体内容
http 协议包头一般以\r\n\r\n(两个 \r\n )结束
HTTP Request and Response
- HTTP请求报文
- HTTP响应报文
Request Header
- Accept:指定客户端能够接收的内容类型
Accept: text/plain, text/html
- Accept-Language:可接受的语言
Accept-Language: en, zh
- Accept-Charset:可接受的字符集;
Accept-Charset: utf-8
- Accept-Encoding:指定浏览器可以支持的web服务器返回内容压缩编码类型
Accept-Encoding:compress,gzip
- Connection:表示是否需要持久连接 (HTTP 1.1默认进行持久连接)
Connection:close
- Cookie:会把保存在该请求域名下的所有cookie值一起发给web服务器
- Content-Length:请求内容长度
- Content-Type:请求内容的类型 Content-type:application/x-www-form-urlencoded;
Response Header
- Access-Control-Allow-Origin:指定哪些网站可以跨域源资源共享
- Age:响应对象在代理缓存中存在的时间,以秒为单位
- Cache-Control:通知从服务器到客户端内的所有缓存机制,表示它们是否可以缓存这个对象及缓存有效时间。其单位为秒
- Content-Encoding:响应资源所使用的编码类型。
- Content-Language:响就内容所使用的语言
- Content-Length:响应消息体的长度,用8进制字节表示;
- Content-Location:所返回的数据的一个候选位置;
- Content-Range:如果是响应部分消息,表示属于完整消息的哪个部分
- Content-Type:当前内容的MIME类型
- Set-Cookie:设置HTTP cookie
HTTP方法
- 常见的有GET, PUT, POST, DELETE, HEAD
GET
- 下面是一个不带参数的GET request
GET /index_2013.php HTTP/1.1\r\n
Host: www.hootina.org\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
\r\n
- 下面是一个带参数的GET request
GET /index_2013.php?param1=value1¶m2=value2¶m3=value3 HTTP/1.1\r\n
Host: www.hootina.org\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
\r\n
HEAD 和 GET的区别
- HEAD (HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URL的有效性及资源更新的日期时间等)
POST
- 下面是一个POST 请求, 用户名和密码放在包体之中(请求最后)
- HTTP服务器有两种方式解析后面的包体
- 第一种方式就是在包头中有个 Content-Length 字段,这个字段的值的大小标识了 POST 数据的长度,上图中 55 就是数据 username=balloonwj%40qq.com&password=iloveyou&appid=otn 的长度,服务器收到一个数据包后,先从包头解析出这个字段的值,再根据这个值去读取相应长度的作为 http 协议的包体数据。
- 还有一个格式叫做 http chunk 技术(分块),大致意思是将大包分成小包,具体的详情可以自行搜索学习。
POST /passport/web/login HTTP/1.1\r\n
Host: kyfw.12306.cn\r\n
Connection: keep-alive\r\n
Content-Length: 55\r\n
Accept: application/json, text/javascript, */*; q=0.01\r\n
Origin: https://kyfw.12306.cn\r\n
X-Requested-With: XMLHttpRequest\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36\r\n
Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n
Referer: https://kyfw.12306.cn/otn/login/init\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
Cookie: _passport_session=0b2cc5b86eb74bcc976bfa9dfef3e8a20712; _passport_ct=18d19b0930954d76b8057c732ce4cdcat8137; route=6f50b51faa11b987e576cdb301e545c4; RAIL_EXPIRATION=1526718782244; RAIL_DEVICEID=QuRAhOyIWv9lwWEhkq03x5Yl_livKZxx7gW6_-52oTZQda1c4zmVWxdw5Zk79xSDFHe9LJ57F8luYOFp_yahxDXQAOmEV8U1VgXavacuM2UPCFy3knfn42yTsJM3EYOy-hwpsP-jTb2OXevJj5acf40XsvsPDcM7; BIGipServerpool_passport=300745226.50215.0000; BIGipServerotn=1257243146.38945.0000; BIGipServerpassport=1005060362.50215.0000\r\n
\r\n
username=balloonwj%40qq.com&password=iloveyou&appid=otn
PUT 和 POST 的区别
- POST不是幂等的, PUT是幂等的
- 所以PUT常常用于对资源的更新(当然也可以用于创建), 比如下面的请求.请求中明确的指定了具体的需要更新或者创建的资源的URL
PUT https://bitmingw.com/2018/04/16/http-put-vs-post HTTP/1.1
{
/* 文章内容正文 */
}
- 如果用POST方法则如下. 没有明确的URL, 需要由服务端生成的。比如,服务端可能会根据日期和文章标题,为本文分配一个地址. 而多次提交下面的请求会创建多个一样的文章
POST https://bitmingw.com/post-article HTTP/1.1
{
/* 文章内容正文 */
}
HTTP状态码
- 200:OK
- 204: No Content
- 304: Not Modified
- 400: Bad Request
- 401: Unauthroized
- 403: Forbidden
- 404: Not Found
- 500: Internal Server Error
- 502: Bad Gateway, 网关或者代理出现问题
- 503: Service Unavailable
HTTP 1.1 / 2.0 特性
keep-alive 长连接
- 在长连接出现之前,http1.0中都是使用的短连接,
- 其特点是一次http交互完成后就会断开连接。由于http协议是基于TCP协议的,而TCP协议有三次握手四次挥手来建立以及断开连接,那么面对多次的http请求,这种短连接就会造成多次的握手以及挥手资源浪费,正是因为这个问题才出现了长连接。
- 在http1.1中,出现了http长连接,其特点是保持连接特性,当一次http交互完后该TCP通道并不会关闭,而是会保持一段时间(在不同服务器上时间不一样,可以设置),如果在这段时间内再次发起了http请求就可以直接复用,而不用重新进行握手,从而减少了资源浪费。目前http1.1中,都是默认使用长连接,在请求头中加上
长连接以及短连接的优缺点
- 长连接:可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。
- 不过这里存在一个问题,在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略。
- 短连接:对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽