一、HTTP简介
HTTP(HyperText Transfer Protocol)即超文本传输协议,是一种详细规定了浏览器和万维网服务器之间互相通信的规则,它是万维网交换信息的基础,它允许将HTML(超文本标记语言)文档从Web服务器传送到Web浏览器。
HTTP协议目前常用的版本是1.1,HTTP是一种无状态的协议,无状态是指Web浏览器与Web服务器之间不需要建立持久的连接,这意味着当一个客户端向服务器端发出请求,然后Web服务器返回响应(Response),连接就被关闭了,在服务器端不保留连接的有关信息。也就是说,HTTP请求只能由客户端发起,而服务器不能主动向客户端发送数据。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
HTTP三点注意事项:
HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
二、http报文格式
HTTP报文传过来都是一堆的0x ASCII码,诸如“41 63 63 65 70 74” 对应的是“accept” 单词的十六进制ASCII码。
这些十六进制的数字经过浏览器或者专用工具比如wireshark的翻译,可以得到HTTP的报文结构。
1.请求报文
以下是wireshark抓出来的一段HTTP请求报文
GET /sid/close.png HTTP/1.1 这是请求行(request line)
Accept: */*
Referer: http://xxx.xxx.xxx.xxx/menu/neo
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)
Accept-Encoding: gzip, deflate
Host: xxx.xxx.xxx.xxx
Connection: Keep-Alive
Cookie: startupapp=neo; is_cisco_platform=0; rdx_pagination_size=250%20Per%20Page; SESSID=deb31b8eb9ca68a514cf55777744e339
HTTP的请求报文包括:请求行(request line)、请求头部(header)、空行 和 请求数据(request data) 四个部分组成。
1.1请求行(request line)
包括: 请求方法,URL(包括参数信息),协议版本这些信息,是上图例子中的(GET /admin_ui/rdx/core/images/close.png HTTP/1.1)
其中请求方法介绍如下:
根据 HTTP 标准,HTTP 请求可以使用多种请求方法。
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1 新增了五种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
序号 | 方法 | 描述 |
1 | GET | 请求指定的页面信息,并返回实体主体。 |
2 | HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | DELETE | 请求服务器删除指定的页面 |
6 | CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | OPTIONS | 允许客户端查看服务器的性能。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
9 | PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 。 |
GET:GET方法用于获取请求页面的指定信息。如果请求资源为动态脚本(非HTML),那么返回文本是Web容器解析后的HTML源代码。GET请求没有消息主体,因此在消息头后的空白行是没有其他数据。
POST:POST方法也与GET方法相似,但最大的区别在于,GET方法没有请求内容,而POST是有请求内容的。
HEAD:这个请求的功能与GET请求相似,不同之处在于服务器不会再其响应中返回消息主体,因此,这种方法可用于检查某一资源在向其提交GET请求前是否存在。
PUT:PUT方法用于请求服务器把请求中的实体存储在请求资源下,如果请求资源已经在服务器中存在,那么将会用此请求中的数据替换原先的数据。向服务器上传指定的资源。
1.2请求头部(Header)
是一个个的key-value值
常见HTTP请求头:
请求头 | 说明 |
Host | 请求报头域主要用于指定被请求资源的Internet主机和端口。 |
User-Agent | 请求报头域允许客户端将它的操作系统、浏览器和其他属性告诉服务器。 |
Referer | 包含一个URL,代表当前访问URL的上一个URL,也就是说,用户是从什么地方来到本页面。当前请求的原始URL地址。 |
Cookie | 是非常重要的请求头,常用来表示请求者的身份等。 |
Accept | 这个消息头用于告诉服务器客户端愿意接受那些内容,比如图像类,办公文档格式等等。 |
Connection | 一般值为 HTTP是无状态无连接的,这里说的是TPC的连接是否可复用。 在 HTTP 1.1 中 所有的连接默认都是持续连接,除非特殊声明不支持。 请求头和响应头都有这个字段,要客户端和服务端都表示支持连接复用才能复用。 从HTTP协议上来说,只要客户端和服务端都 但实际上不同的服务器软件(如nginx)中可设定这个保持时间 。 |
1.3空行(CR+LF)
请求报文用空行表示header和请求数据的分隔
1.4请求数据(request data)
GET方法没有携带数据, POST方法会携带一个body
2.返回报文
下面是wireshark抓出来的一段响应报文
HTTP/1.1 200 OK 这是状态行
Bdpagetype: 1
Bdqid: 0xacbbb9d800005133
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html
Cxy_all: baidu+f8b5e5b521b3644ef7f3455ea441c5d0
Date: Fri, 12 Oct 2018 06:36:28 GMT
Expires: Fri, 12 Oct 2018 06:36:26 GMT
Server: BWS/1.1
Set-Cookie: delPer=0; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=0; path=/
Set-Cookie: H_PS_PSSID=1433_21112_18560_26350_27245_22158; path=/; domain=.baidu.com
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked
<!DOCTYPE html>
<!--STATUS OK-->
HTTP的响应报文包括:状态行,响应头,空行,数据(响应体)
2.1状态行
包括:HTTP版本号,状态码和状态值组成。
HTTP状态码:
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
HTTP状态码的英文为HTTP Status Code。
五种状态码:
1xx:信息提示,表示请求已被成功接收,继续处理。
2xx:请求被成功提交。
3xx:客户端被重定向到其他资源。
4xx:客户端错误状态码,格式错误或者不存在资源。
5xx:描述服务器内部错误。
常见的状态码描述如下:
200:客户端请求成功,是最常见的状态。
302:重定向。
404:请求资源不存在,是最常见的状态。
400:客户端请求有语法错误,不能被服务器所理解。
401:请求未经授权。(比如没登录)
403:服务器收到请求,但是拒绝提供服务。
500:服务器内部错误,是最常见的状态。
503:服务器当前不能处理客户端的请求。
2.2响应头
类似请求头,是一系列key-value值
应答头 | 说明 |
Allow | 服务器支持哪些请求方法(如GET、POST等)。 |
Content-Encoding | 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。 |
Content-Length | 表示内容长度。 |
Content-Type | **表示后面的文档属于什么MIME类型。**Servlet默认为text/plain,但通常需要显式地指定为text/html。 |
Date | 当前的GMT时间。 |
Expires | 应该在什么时候认为文档已经过期,从而不再缓存它? |
Last-Modified | **文档的最后改动时间。**客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。 |
Location | **表示客户应当到哪里去提取文档。**Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。 |
Refresh | 表示浏览器应该在多少时间之后刷新文档,以秒计。注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。 |
Server | 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。 |
Set-Cookie | 设置和页面关联的Cookie。 |
WWW-Authenticate | 客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。 |
2.3空白行
同上,响应报文也用空白行来分隔header和数据
2.4响应体
响应的data,本例中是一段HTML
三、cookie
一个域名下面可能存在着很多个cookie对象。
cookie的属性:
name 字段为一个cookie的名称。
value 字段为一个cookie的值。
domain 字段为可以访问此cookie的域名。
domain属性可以使多个web服务器共享cookie。domain属性的默认值是创建cookie的网页所在服务器的主机名。不能将一个cookie的域设置成服务器所在的域之外的域。
例如让位于a.sodao.com的服务器能够读取b.sodao.com设置的cookie值。如果b.sodao.com的页面创建的cookie把它的path属性设置为"/",把domain属性设置成".sodao.com",那么所有位于b.sodao.com的网页和所有位于a.sodao.com的网页,以及位于sodao.com域的其他服务器上的网页都可以访问这个cookie。
非顶级域名,如二级域名或者三级域名,设置的cookie的domain只能为顶级域名或者二级域名或者三级域名本身,不能设置其他二级域名的cookie,否则cookie无法生成。
顶级域名只能设置domain为顶级域名,不能设置为二级域名或者三级域名,否则cookie无法生成。
二级域名能读取设置了domain为顶级域名或者自身的cookie,不能读取其他二级域名domain的cookie。
所以要想cookie在多个二级域名中共享,需要设置domain为顶级域名,这样就可以在所有二级域名里面或者到这个cookie的值了。
顶级域名只能获取到domain设置为顶级域名的cookie,其他domain设置为二级域名的无法获取。
path 字段为可以访问此cookie的页面路径。
它指定与cookie关联在一起的网页。在默认的情况下cookie会与创建它的网页,该网页处于同一目录下的网页以及与这个网页所在目录下的子目录下的网页关联
比如domain是abc.com,path是/test,那么只有/test路径下的页面可以读取此cookie。
expires/Max-Age 字段为此cookie超时时间。
expires属性
指定了cookie的生存期,默认情况下cookie是暂时存在的,他们存储的值只在浏览器会话期间存在,当用户退出浏览器后这些值也会丢失,如果想让cookie存在一段时间,就要为expires属性设置为未来的一个用毫秒数表示的过期日期或时间点,expires默认为设置的expires的当前时间。现在已经被max-age属性所取代,max-age用秒来设置cookie的生存期。
max-age属性为正数,则表示该cookie会在max-age秒之后自动失效。
浏览器会将max-age为正数的cookie持久化,即写到对应的cookie文件中。
无论客户关闭了浏览器还是电脑,只要还在max-age秒之前,登录网站时该cookie仍然有效。
max-age为负数,则表示该cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该cookie即失效。
max-age为负数的Cookie,为临时性cookie,不会被持久化,不会被写到cookie文件中。
cookie信息保存在浏览器内存中,因此关闭浏览器该cookie就消失了。cookie默认的max-age值为-1。
max-age为0,则表示删除该cookie。
cookie机制没有提供删除cookie的方法,因此通过设置该cookie即时失效实现删除cookie的效果。失效的Cookie会被浏览器从cookie文件或者内存中删除。
如果不设置expires或者max-age这个cookie默认是Session的,也就是关闭浏览器该cookie就消失了。
Size 字段 此cookie大小。
httponly属性
若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie。
这意味着,浏览器脚本,比如javascript中,是不允许访问操作此cookie的。
secure 字段 设置是否只能通过https来传递此条cookie
它是一个布尔值,指定在网络上如何传输cookie,默认是不安全的,通过一个普通的http连接传输。
四、HTTP请求的一个完整过程
1.建立 TCP 连接(之前可能还有一次DNS域名解析)
2.三次握手建立TCP完成后,客户端向服务器发送请求命令,比如 GET https://www.baidu.com?name=xx&addr=xx HTTP1.1
3.客户端发送请求头信息,发送完了header后会接着发送一个空白行,GET请求没有数据,POST请求要发送body数据
4.服务器接收到以上信息后,开始处理业务,处理完有了结果以后,服务器开始应答
5.服务器返回响应头信息,发送完response header以后,再发送一个空白行
6.然后服务器向客户端发送数据
7.发送完了服务器四次挥手关闭 TCP 连接