HTTP协议简介
http协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,用于从万维网(www)传输超文本到本地浏览器的传送协议。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。
http协议是一个应用层协议,由请求和响应构成,是一个标准的c/s(客户端/服务器)模型。
http协议一般承载于传输层的tcp协议上,有时也承载于传输层的tls/ssl协议之上,这时就是https。
版本介绍
HTTP/0.9
- 发布时间:1991年
- 简介:只接受GET一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持POST方法,因此客户端无法向服务器传递太多信息。
- 特点:
- 无状态性,每个事务独立进行处理,事务结束时就释放这个连接
- 只支持GET方法
HTTP/1.0
- 发布时间:1996年5月
- 简介:这是第一个在通讯中指定版本号的HTTP协议版本。同时比 0.9 版本增加大量新特性。非持续连接,每次都要重新与服务器建立连接。
- 特点:
- 支持请求与响应头域
- 响应对象以一个响应状态行开始
- 响应对象不只限于超文本,支持图片、视频、二进制文件
- 支持get、post、head等方法
- 支持长连接(但默认还是使用短连接),缓存机制,以及身份认证
HTTP/1.1
- 发布时间:1997年1月
- 简介:是目前使用最广泛的协议版本。http 1.1引入了许多关键性能优化:keepalive连接,chunked编码传输,字节范围请求,管道机制等。
- 特点:
- Persistent Connection(keepalive连接) 允许http设备在事务处理结束之后将tcp连接保持在打开的状态,以便未来的http请求重用现在的连接,直到客户端或服务器端决定将其关闭为止。在http 1.0中使用长连接需要添加请求头Connection: Keep-Alive,而在http 1.1 所有的连接默认都是长连接,除非特殊声明不支持(http请求报文首部加上Connection: close)。
- chunked编码传输 该编码将实体分块传送并逐块标明长度,直到长度为0块表示传输结束,,这在实体长度未知时特别有用(比如由数据库动态产生的数据)
- 字节范围请求 http 1.1支持传送内容的一部分。比方说,当客户端已经有内容的一部分,为了节省带宽,可以只向服务器请求一部分。该功能通过在请求消息中引入了range头域来实现,它允许只请求资源的某个部分。在响应消息中Content-Range头域声明了返回的这部分对象的偏移值和长度。如果服务器相应地返回了对象所请求范围的内容,则响应码206(Partial Content)。
- 管道机制 1.1 版还引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。 举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。
HTTP/2
- 发布时间:2015 年 5 月
- 简介:HTTP/2 是 HTTP 协议自 1999 年 HTTP 1.1 的改进版 RFC 2616 发布后的首个更新,主要基于 SPDY 协议。它由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组进行开发。该组织于 2014 年 12 月将 HTTP/2 标准提议递交至 IESG 进行讨论,于 2015 年 2 月 17 日被批准。它不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3。
- 特点:
- 二进制协议
- 多工
- 数据流
- 头信息压缩
- 服务器推送
报文格式(HTTP/1.1)
请求报文
请求报文分为 4 个部分,分别是请求行、请求头、换行行、请求数据,每个部分的末尾都会带上回车符(CR,ASCII:0d)和换行符(LF,ASCII:0a)[\t \n]
请求行分为请求方法、请求的 URL 地址、HTTP 版本号,每个字段用空格(ASCII:20)来分隔
请求头部分可以有多行,每行用回车符和换行符区分
通过抓包工具查看报文结构
响应报文
响应报文和请求报文基本差不多,唯一有区别就第一行状态行和请求报文的第一行请求行有区别。
状态行也分为三个部分,分别是 HTTP 版本、状态码、状态码描述,每个部分用空格进行分隔。
响应头和请求头一样,可以有多行
通过抓包工具查看报文结构
请求方法
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
- GET
请求指定的页面信息,并返回实体主体。
- HEAD
类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
- POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
- PUT
从客户端向服务器传送的数据取代指定的文档的内容。
- DELETE
请求服务器删除指定的页面。
- TRACE
回显服务器收到的请求,主要用于测试或诊断。
- OPTIONS
允许客户端查看服务器的性能。
- CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。
- PATCH
是对 PUT 方法的补充,用来对已知资源进行局部更新 。
请求头
| 请求头 | 说明 |
|---|---|
| Accept | Accept: text/html 浏览器可以接受服务器回发的类型为 text/html。 |
| Accept-Encoding | Accept-Encoding: gzip, deflate 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate),(注意:这不是只字符编码)。 |
| Accept-Language | Accept-Language:zh-CN,zh;q=0.9 浏览器申明自己接收的语言。 |
| Connection | Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。 Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。 |
| Host | Host:www.baidu.com 请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。 |
| Referer | Referer:www.baidu.com/?start=1当浏览… |
| User-Agent | User-Agent:Mozilla/...,告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本。 |
| Cache-Control | Cache-Control:private 默认为private 响应只能够作为私有的缓存,不能再用户间共享 Cache-Control:public 响应会被缓存,并且在多用户间共享。正常情况, 如果要求HTTP认证,响应会自动设置为 private. Cache-Control:must-revalidate 响应在特定条件下会被重用,以满足接下来的请求,但是它必须到服务器端去验证它是不是仍然是最新的。 Cache-Control:no-cache 响应不会被缓存,而是实时向服务器端请求资源。 Cache-Control:max-age=10 设置缓存最大的有效时间,但是这个参数定义的是时间大小(比如:60)而不是确定的时间点。单位是[秒 seconds]。 Cache-Control:no-store 在任何条件下,响应都不会被缓存,并且不会被写入到客户端的磁盘里,这也是基于安全考虑的某些敏感的响应才会使用这个。 |
| Cookie | Cookie是用来存储一些用户信息以便让服务器辨别用户身份的(大多数需要登录的网站上面会比较常见),比如cookie会存储一些用户的用户名和密码,当用户登录后就会在客户端产生一个cookie来存储相关信息,这样浏览器通过读取cookie的信息去服务器上验证并通过后会判定你是合法用户,从而允许查看相应网页。当然cookie里面的数据不仅仅是上述范围,还有很多信息可以存储是cookie里面,比如sessionid等。 |
| Range | Range:bytes=0-5 指定第一个字节的位置和最后一个字节的位置。用于告诉服务器自己想取对象的哪部分。 |
| --- | --- |
响应头
| 标题 | |
|---|---|
| Cache-Control | 对应请求中的Cache-Control Cache-Control:private 默认为private 响应只能够作为私有的缓存,不能再用户间共享 Cache-Control:public 浏览器和缓存服务器都可以缓存页面信息。 Cache-Control:must-revalidate 对于客户机的每次请求,代理服务器必须想服务器验证缓存是否过时。 Cache-Control:no-cache 浏览器和缓存服务器都不应该缓存页面信息。 Cache-Control:max-age=10 是通知浏览器10秒之内不要烦我,自己从缓冲区中刷新。 Cache-Control:no-store 请求和响应的信息都不应该被存储在对方的磁盘系统中。 |
| Content-Type | Content-Type:text/html;charset=UTF-8 告诉客户端,资源文件的类型,还有字符编码,客户端通过utf-8对资源进行解码,然后对资源进行html解析。通常我们会看到有些网站是乱码的,往往就是服务器端没有返回正确的编码。 |
| Content-Encoding | Content-Encoding:gzip 告诉客户端,服务端发送的资源是采用gzip编码的,客户端看到这个信息后,应该采用gzip对资源进行解码。 |
| Date | Date: Tue, 03 Apr 2020 03:52:28 GMT 这个是服务端发送资源时的服务器时间,GMT是格林尼治所在地的标准时间。http协议中发送的时间都是GMT的,这主要是解决在互联网上,不同时区在相互请求资源的时候,时间混乱问题。 |
| Server | Server:Tengine/1.4.6 这个是服务器和相对应的版本,只是告诉客户端服务器信息。 |
| Transfer-Encoding | Transfer-Encoding:chunked 这个响应头告诉客户端,服务器发送的资源的方式是分块发送的。一般分块发送的资源都是服务器动态生成的,在发送时还不知道发送资源的大小,所以采用分块发送,每一块都是独立的,独立的块都能标示自己的长度,最后一块是0长度的,当客户端读到这个0长度的块时,就可以确定资源已经传输完了。 |
| Expires | Expires:Sun, 1 Jan 1994 01:00:00 GMT 这个响应头也是跟缓存有关的,告诉客户端在这个时间前,可以直接访问缓存副本,很显然这个值会存在问题,因为客户端和服务器的时间不一定会都是相同的,如果时间不同就会导致问题。所以这个响应头是没有Cache-Control:max-age=*这个响应头准确的,因为max-age=date中的date是个相对时间,不仅更好理解,也更准确。 |
| Last-Modified | Last-Modified: Dec, 26 Dec 2019 17:30:00 GMT 所请求的对象的最后修改日期(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示) |
| Connection | Connection:keep-alive 这个字段作为回应客户端的Connection:keep-alive,告诉客户端服务器的tcp连接也是一个长连接,客户端可以继续使用这个tcp连接发送http请求。 |
| Etag | ETag: "637060cd8c284d8af7ad3082f209582d" 就是一个对象(比如URL)的标志值,就一个对象而言,比如一个html文件,如果被修改了,其Etag也会别修改,所以,ETag的作用跟Last-Modified的作用差不多,主要供WEB服务器判断一个对象是否改变了。比如前一次请求某个html文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得ETag值发送给WEB服务器,然后WEB服务器会把这个ETag跟该文件的当前ETag进行对比,然后就知道这个文件有没有改变了。 |
| Refresh | Refresh: 5; url=baidu.com 用于重定向,或者当一个新的资源被创建时。默认会在5秒后刷新重定向。 |
| Access-Control-Allow-Origin | Access-Control-Allow-Origin: * 号代表所有网站可以跨域资源共享,如果当前字段为那么Access-Control-Allow-Credentials就不能为true Access-Control-Allow-Origin: www.baidu.com 指定哪些网站可以跨域资源共享 |
| Access-Control-Allow-Methods | Access-Control-Allow-Methods:GET,POST,PUT,DELETE 允许哪些方法来访问 |
| Access-Control-Allow-Credentials | Access-Control-Allow-Credentials: true 是否允许发送cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。如果access-control-allow-origin为*,当前字段就不能为true |
| Content-Range | Content-Range: bytes 0-5/7877 指定整个实体中的一部分的插入位置,它也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。 |
| --- | --- |
状态码
常见状态码
- 200 请求成功
- 303 重定向,把你重定向到其他页面
- 400 客户端请求的语法错误,服务器无法理解
- 401 请求要求用户的身份认证
- 404 服务器无法根据客户端的请求找到资源(网页)
- 405 客户端请求中的方法被禁止
- 500 服务器内部错误,无法完成请求
- 502 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应