HTTP详解(更新完结)
一、网络协议基础
osi中模型有七层,分别是物理层,数据链路层,网络层,传输层,会话层,表示层,应用层
五层的网络协议中有,物理层,数据链路层,网络层,运输层,应用层
2、其中各层的作用如下
(1)物理层,就是定义物理设备的标准,比如网线的接口类型没传输介质的传输速率等,主要是传输比特流,就是(将1,0转换为电流强弱来进行传输,到达目的地后就转化为1,0,也就是数模转换和模数转换),传输的数据是比特。(其实就是网线那里的协议)
(2)数据链路层,我的理解就是从物理层传输过来的数据封装成帧(在数据前后添加首部和尾部),主要作用在交换机和网桥,这里有三个很重要的问题就是封装成帧,透明传输以及差错检测。
其中封装成帧就是接受端在收到物理层上交的比特流之后,能根据首部和尾部的标记,从收到的比特流中识别帧的开始于结束,然后发送出去
而透明传输就是只要有数据就传出去,保证了数据一定会被传输出去,也就是说不管什么样的字符都可以放在这样的帧传输过去。
差错就测就是检测帧里面的比特哪里有错,并且把它进行修改。
(3)网路层也即是我们ip协议作用的地方了。在不同地理位置的网络中的两个主机系统之间提供链接和路径的选择(就是当交换机把数据发送出去,到了网络成之间,根据两个主机的地址而选择不同的网络路由)
(4)传输层,定义了传输数据的协议和端口号,就是之前ping端口是不对的,因为端口它是在传输层,Tcp,Udp,也是作用在这里,就是将下层接收过来的数据进行分段和传输,到达目的地址再进行重组,这一层的数据叫段。(tcp三次握手四次挥手大家都懂)
(5.)会话层,通过传输层(端口号:传输端口与接收端口)建立数据传输的通路,主要在系统之间发起或者接收会话请求
(6)表示层:确保一个系统的应用层发送的信息可以被另一个系统的应用层读取
(7)应用层:报文,也即是两个软件之间的通信。
所以普通五层协议以及TCP\IP中的应用层就包含了应用层、表示层、会话层,所以比如邮件服务(SMTP),文件传输(FTP)和终端仿真(Telnet)等都是在这里
3、ip,mac,arp
IP地址指明了节点被分配到的地址,MAC地址是指网卡所属的固定地址。IP地址可以和MAC地址进行配对,IP地址可变换,但MAC地址基本上不会更改。
利用ARP协议凭借MAC地址进行通信。
IP之间的通信依赖MAC地址。在网络上,通信双方在同一局域网内的情况很少,通常是经过多态计算机和网络设备中专才能连接到对方。而在进行中转事,会利用下一站中转设备的MAC地址来搜索CIA一个中转目标。这是,会采用ARP协议。ARP是一种用来解析地址的协议,可以根据IP地址查出对应的MAC地址,
4、TCP
按层次分,TCP位于传输层,提供可靠的字节流服务。
字节流服务就是为了方便传输,将大块的数据分隔以报文段为单位的数据包进行管理。而可靠的传输服务是指,能够把数据准确可靠地传给对方。也就是说,TCP是为了更容易的传输大数据才把数据进行分隔。
另一方面,TCP为了能够确保数据能够送达对方,采用了三次握手。用TCP协议把数据包传输出去后,TCP一定会向对方确认是否成功送达,这个过程使用了两个flag,分别是SYN,ACK。
发送算首先发送一个带SYN标志的数据包给对方,接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息,最后发送端再回传一个带ACK标志的数据包,代表握手结束。
5、DNS,位于应用层的域名解析服务,提供域名和IP地址之间的解析服务。
二、http基础
1、http是建立在tcp\ip协议的基础上的。所以这里的层级采用的四层,分别是应用层,传输层,网络层以及接口层。
所以当一个客户端发起请求的时候,主要顺序如下
首先作为发送端的客户端在应用层(http协议)发出一个想要某个web页面的http请求。
然后为了传输方便,在传输层(TCP)协议把从应用层收到的数据进行分割后在各个报文上打上标记序号以及端口号转发给网络层
在网络层中 链路层,这样发送网络的请求就准备好了
接受端的服务器在链路层中接收到数据,按序往上层发送,一直到应用层,当传输到应用层的时候,才能真正接受到由客户端发送过来的HTTP请求。
2、URI和URL的区别
URI是uniform resource identifier的缩写,也就是统一资源标识符,就是由某个协议方案表示的资源的定位标识符
URL是资源所在的地址,所以URL是URI的子集。
URI不一定是URL,但URL一定是URI
3、简单的http协议
(1)http协议是用于客户端和服务器之间的通讯,http协议规定,请求从客户端发出,最后服务器响应该请求并返回,也就是说,一定是客户端先发起通信的。
(2)在请求头中
GET /index.html HTTP/1.1
Host:banma.com
上面中的第一行指定了请求的方法、请求的资源、http的版本号
这一行的意思就是,请求某台http服务器上的/index.html页面资源
而请求报文中,是由请求方法、请求URI、协议版本、可选的请求首部字段和内容实体构成的
前三者是第一行,后面的是请求首部,再然后是内容实体,比如
GET /index.html HTTP/1.1
Host:banma.com
Connection:keep-alive
Content-Type:application/x-www-form-urlencoded
Content-Length:16
name=krysliang&age=23
在上面的代码中,2-5行是请求首部字段,最后一行是内容实体
接收到这样的请求后服务器会返回类似于下面这样的response
HTTP/1.1 200 OK
Date:Tue,21 May 2019 15:57:16 GMT
Content-Length:362
Content-Type:text/html
<html>…..
在第一行中表明了http的版本号,状态码和原因
2-4行中显示了创建响应的日期时间,还有首部的一些字段
最后的是响应的实体部分,也叫body
(3)http是不保存状态的协议,http协议自身不对请求和响应之间的通信状态进行保存,也就是说在http这个级别,协议对于发送过的请求或响应都不做持久化处理。换句话说,就是一个request对应一个response,每次有新的请求发送的时候,就会有对应的新响应产生,这是为了更快的处理大量事务,而把HTTP设计成这么简单的,
(4)URI
HTTP协议使用URI定位互联网上的资源。正式因为URI的特定功能,在互联网上任意位置的资源都能访问到。
请求URI的方式可以有多种,比如
如果不是访问特定资源,而是对服务器本身发起请求,可以用一个*来代替请求URI。
(5)METHOD
GET获取资源
GET方法用来请求访问资源,指定的资源经过服务器解析后返回响应内容,也就是说,如果GET请求的资源是文本,那么将保持原样返回,如果是程序,那么将返回经过执行后的输出结果。
请求 |
GET /index.html HTTP/1.1 |
响应 |
返回index.html的页面资源 |
请求 |
GET /index.html HTTP/1.1 Host: www.krysliang.com If-Modified-Since: Thu, 12 Jul 2019 07:30:00 GMT |
响应 |
仅返回2019年7 月12日7 点30分以后更新过的index.html页面资源。如果未 有内容更新,则以状态码304 Not Modified作为响应返回 |
POST 传输实体
POST用来传输实体的主体,也就是说可以传输form表单等数据给服务器,虽然GET也可以传输实体的主体,但一般不用GET方法进行传输。
请求 |
POST /submit.cgi HTTP/1.1 Host:www.krysliang.com Content-Length:1560 |
响应 |
返回submit.cgi接收数据的处理结果 |
PUT 传输文件
PUT方法用来传输文件。在请求主体中包含文件的内容,然后保存到请求URI指定的位置。一般不用这个方法来上传文件,因为这个方法不带验证功能,所以会造成安全性的问题。
请求 |
PUT /example.html HTTP/1.1 Host:www.krysliang.com Content-Type: text/html Content-Length: 1560(1560 字节的数据) |
响应 |
响应返回状态码 204 No Content(比如 :该 html 已存在于服务器上) 204是请求执行成功了,但无数据返回 |
HEAD 获得报文首部
HEAD和GET方法一样,但是不返回报文主体部分,用来确认URI的有效性及资源更新的日期时间等信息。
请求 |
HEAD /index.html HTTP/1.1 Host:www.krysliang.com |
响应 |
返回index.html有关的响应首部 |
DELETE 删除文件
DELETE方法按请求URI删除指定的资源。跟PUT有点像,也是因为安全性不好,一般不使用
OPTIONS:询问支持的方法
OPTIONS用来查询指定URI资源所支持的方法
请求 |
OPTIONS * HTTP/1.1 Host:www.krysliang.com |
响应 |
HTTP/1.1 200 OK Allow:GET,POST,HEAD,OPTIONS |
TRACE:追踪路径
将客户端请求到服务器这个过程的通信环返回给客户端。
原理:发送请求的时候,再Max-Forwards首部字段中填入数值,每经过一个服务器端就将该数字减1,当数值刚好减到0的时候,则停止传输,最后收到请求的服务器则返回状态吗200 OK的响应。
但是这个方法容易引发跨站追击的攻击。一般都不要使用。
请求 |
TRACE / HTTP/1.1 Host: www.krysliang.com Max-Forwards: 2 |
响应 |
HTTP/1.1 200 OK Content-Type: message/http Content-Length: 1024 TRACE / HTTP/1.1 Host: www.krysliang.com Max-Forwards: 2(返回响应包含请求内容 |
CONNECT:要求使用隧道协议连接代理
CONNECT方法要求在与代理服务器通信的时候建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(安全套接字)和TLS(传输层安全)协议把通信内容加密后经网络隧道传输
格式如下
CONNECT 代理服务器名:端口号 HTTP版本
详细的可以看这个博客https://www.joji.me/zh-cn/blog/the-http-connect-tunnel/
(6)持久化连接
http协议初始版本中,每进行一次http通信就要断开一次TCP连接
这样的话,当传输大量的资源的时候就会造成无畏的TCP连接建立和断开,增加通信量的开销。
持久化的意思就是,只要任意一段没有明确提出断开连接,则保持TCP连接状态。这样就减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器的负载。
此外,使用持久连接还有另一个好处,就是可以使用管线化的方式来进行发送
什么?什么是管线化?
来。
管线化的意思就是,只要建立起了TCP连接,一个HTTP请求不用等到对应的响应再开始发送下一个HTTP请求。一个管线一个请求或者响应。比如,当请求一个包含10张图片的HTML页面,管线化就可以一下子请求10个图片以及一个html页面。
看图
(7)cookie
因为http是无状态协议,也就是说它不对之前发生过的请求和响应的状态进行管理,也就是说,无法根据之前的状态进行本次的请求处理。假设要求登录认证的页面本身无法进行胡葬台的管理,那么每次跳转新的页面就要再次登录,就是要在每次请求报文中附加参数来管理登录状态,这无疑又给服务器增加了新的压力。于是引入了cookie,cookie通过请求和响应报文中写入cookie信息来控制客户端的状态。
服务端发送回来的响应报文中有一个Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往服务端发送请求的时候,客户端将自动在请求报文中加入cookie值后再发送出去。
服务端发现客户端发送过来的Cookie后,会去检查究竟是从哪一个客户端发过来的连接请求,然后对比服务端上的记录,最后得到之前的状态信息。
1. 请求报文(没有 Cookie 信息的状态)
GET /reader/ HTTP/1.1
Host: www.krysliang.com
*首部字段内没有Cookie的相关信息
2. 响应报文(服务器端生成 Cookie 信息)
HTTP/1.1 200 OK
Date: Thu, 12 Jul 2012 07:12:20 GMT
Server: Apache
<Set-Cookie: sid=1342077140226724; path=/; expires=Wed,
10-Oct-12 07:12:20 GMT>
Content-Type: text/plain; charset=UTF-8
3. 请求报文(自动发送保存着的 Cookie 信息)
GET /image/ HTTP/1.1
Host: www.krysliang.com
Cookie: sid=1342077140226724
三、HTTP里面的信息
1、什么是HTTP报文
用于HTTP协议交互的信息叫做HTTP报文。请求端的叫做请求报文,响应端的叫做响应报文,
HTTP报文本身是由多行数据构成的字符串文本。
其分为两部分,分别是首部和主体,两者用空行分隔开,一个报文中不一定有注意。
2、报文首部格式
(1)HTTP请求报文首部
在请求报文中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等构成。
如:
GET / HTTP/1.1
Host: www.krysliang.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*; q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
If-Modified-Since: Fri, 31 Aug 2007 02:02:20 GMT
If-None-Match: "45bae1-16a-46d776ac"
Cache-Control: max-age=0
(2)HTTP响应报文首部
响应报文首部由HTTP版本、状态码、HTTP首部字段3部分构成。
如:
HTTP/1.1 304 Not Modified
Date: Thu, 07 Jun 2012 07:21:36 GMT
Server: Apache
Connection: close
Etag: "45bae1-16a-46d776ac"
(3)HTTP首部字段
从上面可以看出,无论是请求报文还是响应报文,都有HTTP首部字段,可以看得出它蛮重要的。首部字段是给浏览器和服务器提供报文主体大小、所使用的语言等内容。
首部字段结构:HTTP首部字段是由首部字段名和字段值构成,中间用冒号":"分隔,如
Content——Type:text/html
此外字段可以拥有多个值,如
Keep-Alive: timeout=15, max=100
4种HTTP首部字段类型
HTTP首部字段分为以下几种:通用首部字段(也就是请求报文和响应报文两方都会使用的首部),请求首部字段,响应首部字段,实体首部字段
首部字段
通用首部字段
首部字段名 |
说明 |
Cache-Control |
控制缓存的行为 |
Connection |
逐跳首部、链接的管理 |
Date |
创建报文的日期时间 |
Pragma |
报文指令 |
Trailer |
报文末端的首部一览 |
Transfer-Encoding |
指定报文主体的传输编码方式 |
Upgrade |
升级为其他协议 |
Via |
代理服务器的相关信息 |
Warning |
错误通知 |
请求首部字段
首部字段名 |
说明 |
Accept |
用户代理可处理的媒体类型 |
Accept-Charset |
优先的字符集 |
Accept-Encoding |
优先的内容编码 |
Accept-Language |
优先的语言 |
Authorization |
web认证信息 |
Expect |
期待服务器的特定行为 |
From |
用户的电子邮箱地址 |
Host |
请求资源所在服务器 |
If-Match |
比较实体标记(ETag) |
If-Modified-since |
比较资源的更新时间 |
If-Unmodified-Since |
比较资源的更新时间 |
Max-Forwards |
最大传输逐跳数 |
Proxy-Authorization |
代理服务器要求客户端的认证信息 |
Range |
实体的字节范围请求 |
Referer |
对请求中URI的原始获取方 |
TE |
传输编码的优先级 |
User-Agent |
HTTP客户端程序的信息 |
响应首部字段
首部字段名 |
说明 |
Accept_Ranges |
是否接受字节范围请求 |
Age |
当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了(也就是距离第一次问服务器请求获得资源的时间) |
ETage |
资源的匹配信息 |
Location |
令客户端重定向至指定URI |
Proxy-Authenticate |
代理服务器对客户端的认证信息 |
Retry-After |
对再次发起请求的时机要求 |
Server |
HTTP服务器的安装信息 |
Vary |
代理服务器缓存的管理信息 |
WWW-Authenticate |
服务器对客户端的认证信息 |
实体首部字段
首部字段名 |
说明 |
Allow |
资源可支持的HTTP方法 |
Content_Encoding |
实体主体适用的编码方式 |
Content-Language |
实体主体的自然语言 |
Content-Location |
替代对应资源的URI |
Content-Length |
实体主体的大小(字节) |
Content-MD5 |
实体主体的报文摘要 |
Content-Type |
实体主体的媒体类型 |
Expires |
实体主体过期的日期时间 |
Last-Modified |
资源的最后修改日期时间 |
3、HTTP中的编码
HTTP在传输数据的时候开业按照数据原貌直接传输,也可以在传输过程汇总通过编码提升传输速率。通过在传输时编码可以有效的处理大量的访问请求,但是编码的操作需要计算机来完成,因此会消耗更多的CPU资源。
(1)压缩传输的内容编码,这个编码方式有gzip、compress、deflate、identity(不进行编码)
压缩内容的意思就是服务器端将实体进行压缩编码,然后再客户端进行解码。
(2)分隔发送的分块传输编码
如果在请求的编码实体资源尚未全部传输完成之前,浏览器将无法显示请求页面,那么在传输大容量数据的时候,通过把数据分隔成多块,能够让浏览器逐步显示页面。换句话说,分块传输编码就人如其名,是将资源进行分块然后传输的编码。
详细的可以看这里https://foofish.net/http-transfer-encoding.html
我的理解就是,TCP不是管线化嘛,然后HTTP也是持久连接嘛,所以当一个请求头部 指定了Transfer-Encoding: chunked的时候,那么这个request对应的response将会分成多个块回传给客户端,客户端拿到一个就先显示一个,然后遇到最后一个长度为0的response就等于这个request对应的response传输结束了。
4、状态码
状态码就是描述返回的请求结果,根据状态码可以判断服务器处理请求的结果。
(1)状态码的组成:3位数字和原因短语,如果200 OK
(2)状态码的分类
类别 |
原因短语 |
|
1XX |
Information(信息) |
接收的请求正在处理 |
2XX |
Success(成功) |
请求正常处理 |
3XX |
RedirectCtion(重定向) |
需要进行附加操作以完成请求 |
4XX |
Client Error(客户端错误) |
服务器无法处理请求 |
5XX |
Server Error(服务器错误) |
服务器处理请求出错 |
2XX
1)200 OK
这个状态码表示请求被正常处理了。在响应报文中,随状态码一起返回的信息(body)会因方法的不同而发生改变。比如,使用GET的方法,对应请求资源的实体会作为响应返回,而HEAD则不会返回
2)204 NO Content
该状态码表示服务器接收的请求已经成功处理了,但是返回的response中不包含body部分,也就是没有主题部分。一般发生在只需要从客户端给服务器发送信息,但对客户端 不需要发送新信息内容的情况下使用
3)206 Partial Content
该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。response中包含Content-Range指定范围的实体内容(字节范围)。
3XX 重定向
3XX的状态码表示浏览器需要执行某些特殊的处理然后才能正确的处理请求。
1)301 Moved Permanently 永久性重定向
该状态码表示请求的资源已经被分配了新的URI,以后应使用资源现在所指向的URI。也就是说,如果已经把资源对应的URI保存为书签了,这是应该按首部字段Location提示的URI重新保存
2)302 Found 临时性重定向
改状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问
3)303 See Other
该状态码表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。什么意思呢?就是说,希望你用另一个URI然后GET去请求它。
那么301,302,303之间有什么区别呢?
301就是永久重定向,以后该资源都会使用该重定向的URI,302就是临时,以后这个URI还是有可能会发生变化的,303跟302有点像,但是303明确的表示客户端应该使用GET来获取资源。
比如说,当使用POST方法来访问一个程序,其执行后的结果是希望客户端能以GET方法重定向到另一个URI上去,则返回303。
当301,302,303出现的时候,大部分的浏览器都会将POST改成GET,并删除请求报文内的body,之后请求会自动再次发送。
4)304 Not Modifiled
之前使用vue来构建一个管理系统的时候,就出现过这个状态码,后来发现是由于webpack的原因。哭唧唧。
该状态码表示客户端发送附带请求的时候( GET 方法的请求报文中包含 If-Match,If-Modified-
Since,If-None-Match,If-Range,If-Unmodified-Since 中任一首部。),服务器端允许请求访问资源,但未满足条件的情况,则返回该状态码,response中不包含任何body。
5)307 Temporary Redirect 临时重定向
跟302有点像,不同的是,307出现的时候不会讲POST改成GET,而是遵守标准。
4XX 客户端错误
1)400 Bad Request
该状态码表示request中存在语法错误,需要修改了错误后再次发送。
2)401 Unauthorized 未认证
该状态码表示,访问服务器需要认证或者认证失败。
出现该错误的response中必须含有一个适用于请求资源的www-authenticate的首部,用来验证用户的信息。
4)403 Forbidden
该状态码表示,服务器拒绝访问该资源。
想看到详细的理由,如果服务器有给出的话,可以在response中的body部分看到。
5)404 Not Found
该状态码表示没有此资源。
5XX 服务器错误
1)500 Internal Server Error
该状态码表示服务器在执行请求的时候发生了错误。
2)503 Service Unavailable
该状态码表示服务器暂时处于超负载或者正在进行停机维护,现在无法处理请求。
四、一些跟HTTP相关的网络知识
1、虚拟主机
虚拟主机就是,几个不同的域名其实指向着同一台服务器,也就是说,一台服务器可以运行各自不同的网站。
但是虚拟主机不是云服务器,云服务器是群服务器中的一台。
所以当一个服务器中托管了两个不同的域名,当收到请求的时候就需要搞清楚究竟要访问哪个域名了。所以在发送HTTP请求的时候,必须在HOST首部内完整指出主机名或域名的URI。
2、在客户端与服务器之间通信的时候,中间会有一些用来转发数据的机器和对应的应用程序,比如代理、网关、隧道等。
这些应用程序和服务器可以将请求转达给通信线路上的下一站服务器,并且能接受从那台服务器发送滚动响应再转发给客户端。
3、代理
代理是一种有转发功能的应用程序,是客户端和服务器之间的中间人,接受由客户端发送的请求并转发给服务器,同时,也接收服务器返回的响应并转发给客户端。
在HTTP通信的过程中,可以级联多台代理服务器。请求和响应的转发会经过书台类似锁链一样连接起来的代理服务器。转发时,需要附加Via首部字段以标记处经过的主机信息。
缓存代理:代理转发响应的时候,缓存代理会预先将资源的副本保存在代理服务器上,当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获得资源,而是将之前缓存的资源作为响应返回。
缓存是具有有效期的,
透明代理 :转发请求或响应的时候,不对报文做任何加工。
非透明代理:转发请求或响应的时候,对报文内容进行加工
4、网关
网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,就像自己拥有资源的源服务器一样对请求进行处理。
5、隧道
隧道的目的是确保客户端能与服务器进行安全的通信,隧道本身不会去解析HTTP请求。也就是说,请求保持原样中转给之后的服务器,隧道会在通信双方断开连接时结束。
五、首部字段详解
(一)通用首部字段
1、Cache-Control
这个首部字段是用来控制缓存的,其还包含很多子指令,多个子指令之间用逗号分开,用来控制缓存的工作机制。
其中子指令还可以分为请求和响应两个部分
(1)缓存请求指令
指令 |
参数 |
说明 |
no-cache |
无 |
强制向源服务器再次验证(也就是说我不想要代理服务器的缓存内容,我想要服务器中最新的资源) |
no-store |
无 |
不希望代理服务器去缓存请求或者响应的任何内容 |
max-age=[] |
必须,单位为秒 |
能够接受已经过去多久的缓存 |
min-fresh=[] |
必须,单位为秒 |
要求缓存服务器返回至少还没过指定时间的缓存时间,也就是说,比如指定该值为60,超过了60秒的资源都没有办法作为响应返回了。 |
max-stale([]) |
可省略,单位为秒 |
可接受过期多久的响应,如果指令中未指定参数,那么无论过了多久,客户端都会接受想用;如果指令中指定了具体数值,那么即使过期,只要仍处于指定数值内,仍旧会被客户端接收。 |
no-transform |
无 |
代理服务器不可以对响应实体作任何处理和改变 |
only-if-cached |
无 |
从缓存中获取资源,也就是说只要缓存服务器中的资源,如果有则返回,如果没有则返回504的状态码。 |
(2)响应中跟缓存相关的指令
指令 |
参数 |
说明 |
public |
无 |
任何请求都可以接受响应的缓存 |
private |
可省略 |
仅向特定的用户返回响应 |
no-cache |
可省略 |
缓存前必须要确定其有效性 |
no-store |
无 |
不缓存请求或响应的任何内容 |
no-transform |
无 |
代理服务器不可更改媒体类型 |
must-revalidate |
无 |
可缓存但必须再向源服务器进行确认 |
proxy-revalidate |
无 |
要求代理服务器对缓存的响应有效性再进行确认 |
max-age=[] |
必须,单位是秒 |
响应的最大的age值,也就是说如果Age已经超过这个值,就要向源服务器再次请求资源 |
s-maxage=[] |
必须,单位是秒 |
公共缓存服务器响应的最大Age值,跟上面的max-age相同,不同的是这里的代理服务器应为供多位用户使用的公共缓存服务器 |
(3)no-cache
no-cache在request和response中的行为是不一样的,在request中代表客户端希望直接获取源服务器的资源,因此代理服务器必须将request转发给源服务器。在response中代表服务器不允许代理服务器进行缓存
如果response中的no-cache有参数,代表,客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存,无参数的时候,代理服务器可以进行缓存,但是每次使用需要跟源服务器进行确认。
(4)max-age,s-maxage
Cache-Control: max-age=604800(单位:秒)
在request中的max-age中带包,如果资源的缓存时间比指定的时间数值更小,那么客户端就接收缓存的资源,当max-age为0的时候,缓存服务器通常需要将请求转发给源服务器。
在response中的max-age,在指定的时间内无需再向源服务器进行有效性确认。
2、Connection
这个通用首部字段有两个作用
(1)管理持久化连接
因为HTTP/1.1之后的都会默认连接时持久化连接,所以当服务器想要明确断开连接的时候,则指定Connection首部字段的值为close,而在HTTP/1.1之前的都会默认为是非持久连接,所以如果想在旧版本上面维持持久连接则将该字段设置为Keep-Alive
Connection:close
Connection:Keep-Alive
(2)控制不再转发给代理的首部字段
3、Date
这个字段表明创建HTTP报文的日期和时间
Date: Tue, 03 Jul 2012 04:40:59 GMT
4、Pragma
这个字段是HTTP/1.1之前遗留下来的,其值为指令
如
Pragma: no-cache
5、Trailer
这个字段的作用就是事先说明报文主体之后记录了哪些首部字段。
HTTP/1.1 200 OK
Date: Tue, 03 Jul 2012 04:40:56 GMT
Content-Type: text/html
...
Transfer-Encoding: chunked
Trailer: Expires
...(报文主体)...
0
Expires: Tue, 28 Sep 2004 23:59:59 GMT
6、Transfer-Encoding
7、Upgrade
这个字段用于检测HTTP协议及其他协议时候可以使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议
需要注意的是此处的Connection是Upgrade,因为Upgrade这个字段产生作用的Upgrade对象仅限于客户端和邻接服务器之间,因此为了保证整个通信链的畅通,需要在Connection中指定Upgrade
8、Via
这个字段是用来追踪客户端与服务器之间的请求和响应报文的传输路径。
报文经过代理或网关的时候,会先在首部字段Via中附加该服务器的地址等信息,然后再进行转发。
在上面的例子中,经过代理服务器A的时候,,Via 首部附加了“1.0
gw.hackr.jp (Squid/3.1)”这样的字符串值。行头的 1.0 是指接收请求的服务器上的HTTP的版本,之后的B也是这样
9、Warning中的一些警告码
警告码 |
警告内容 |
说明 |
110 |
Response is stale(响应已过期 |
代理返回已过期的资源 |
111 |
Revalidation failed(再验证失败) |
代理再验证资源有效性时失败(服务 器无法到达等原因 |
112 |
Disconnection operation(断开连接操 作 |
代理与互联网连接被故意切断 |
113 |
Heuristic expiration(试探性过期 |
响应的使用期超过24小时(有效缓存 的设定时间大于24小时的情况下) |
199 |
Miscellaneous warning(杂项警告) |
任意的警告内容 |
214 |
Transformation applied(使用了转换 |
代理对内容编码或媒体类型等执行了 某些处理时 |
299 |
Miscellaneous persistent warning(持久 杂项警告 |
任意的警告内容 |
(二)、请求首部字段
1、Authorization
这个字段是用来告知服务器,用户代理的认证信息,
2、Expect
这个字段用来告知服务器,期望其作出的特定行为
3、From
用来告知服务器,使用用户代理的用户的电子邮件地址。使用代理是,应尽可能的包含次字段。
4、Host
请求资源的主机名和端口号。
这个字段蛮重要的,比如,当我们地址请求一个部署了多个域名的服务器的时候,经过dns解析之后到达的已经是同一个ip的服务器了,此时如果没有设置Host,服务器将无法知道请求的是哪个域名。
5、If-Match
条件请求,服务器接收到附带条件的请求后,只有判断指定条件为真的时候,才会执行请求。
6、If-Modified_Since
这个字段会告知服务器若If-Modified-Since这个字段值早于资源的更新时间,则希望能够处理该请求,否则返回304 NotMOdified。这个字段用于确认代理或客户端拥有的本地资源的有效性。获得资源的更新日期时间,可以使用Last-Modified来确定。
7、If-None-Match
只有当此值与ETag的值不一致的时候,才会处理这个请求,与If-Match相反。
8、If-Range
这个字段跟Range字段一起混合使用共同作用,当If-Range的值与资源的Etag或者与资源更新的日期时间相一致,那么则返回Range范围内的内容,否则,返回全部内容。
9、If-Unmodified-Since
这个字段与If-Modified-Since相反,此字段告诉服务器,指定的请求资源只有在字段值内指定的日期时间之后未发生更新的情况下,才能处理请求,否则返回412的状态码。
10、Max-Forwards
用来指定中间中转的服务器的个数
通过TRACE或者OPTIONS方法,发送包含首部字段Max-Forwards的请求的时候,该字段以十进制整数形式指定可经过的服务器的最大数目。服务器在往下一个服务器转发请求之前, 该值减1后再重新赋值。当服务器收到Max-Forwards的值为0的请求的时候,则不再进行互赞发,而是直接返回响应。
使用 HTTP 协议通信时,请求可能会经过代理等多台服务器。途中,
如果代理服务器由于某些原因导致请求转发失败,客户端也就等不到
服务器返回的响应了。对此,我们无从可知。
11、Proxy-Authorization
这个是客户端与代理之间的认证。当客户端接收到从代理服务器发来的认证质询的时候,客户端会发送包含该字段的请求,以告知服务器认证所需的信息。
12、Range
指定请求部分资源的字节范围,
Range: bytes=5001-10000
上面代码的意思是请求获取从第50001字节到10000字节之间的资源。接收带附带Range字段的请求的服务器,会在处理请求之后返回状态码为206 Partcial Content的响应,无法处理的时候则返回状态码200 OK以及全部资源。
13、Referer
这个首部字段会告知服务器请求的原始资源的URI。
客户端一般都会发送Referer这个字段给服务器。但当直接在浏览器的地址栏输入URI的时候,处于安全性的考虑,也可以不发送该首部字段
14、TE
这个字段会告知服务器,客户端能够处理响应的传输编码方式以及相对优先级。它和Accept-Encoding很像,但是用于传输编码。
首部字段 TE 除指定传输编码之外,还可以指定伴随 trailer 字段的分
块传输编码的方式。应用后者时,只需把 trailers 赋值给该字段值。
TE: trailers
15、User-Agent
这个字段是用来传达浏览器和用户代理等信息
(三)、响应首部字段。
1、Accept-Ranges
用来告诉客户端,服务器是否能够正确处理范围请求,以指定获取服务器某个部分的资源。该值有两个,可以处理范围请求的时候指定为其byte,反之指定为none。
2、Age
这个字段能告知客户端,源服务器在多久前创建了响应,字段值的单位为秒。
若创建该响应的服务器是缓存服务器,Age值是指缓存后的响应再次发起认证到认证完成的时间值。
3、ETag
这个字段是用来告知客户端实体的标志,它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag
需要注意的是,资源被缓存的时候,英文版和中文版的网站,虽然资源的路径是一样的,但是其在缓存服务器上对应的资源是不一样的,也就是说,同一个URI,中文版和英文版对应的是两个ETag不一样的资源
此外ETag还有强弱之分,强的ETag是,只要资源有一点点的变化都会改变其值,而弱ETag是,只有当资源发生了根本性的变化,其值才会发生变化。
4、Locatoin
这个字段通常伴随着301——303状态码的发生,代表资源发生重定向的时候,指向资源现在所在的位置。当客户端收到带有此字段的response的时候,都会强制性的尝试对一体式的重定向资源的访问。
5、Proxy-Authenticate
不同于request中的此字段,response的此字段是把代理服务器要求的认证消息发送给客户端。
6、Retry-After
这个字段告诉客户端,服务器现在正在忙,请你在指定的时间再来访问,通常伴随503 Service-Unvaliable响应。此字段值可以是具体的时间也可以是创建响应后的秒数
7、Vary
此字段一般是源服务器发送给代理服务器的,用来控制缓存的动作。
比如,下面这个图中,request中指定的Accept-Lanuguage,response返回Vary指定了Accept-Langua,就是说,只有指定了该Accept-Language并且值是对的上的,才会给返回缓存。否则要从源服务器中重新获取资源。
(四)、实体首部字段
1、Allow
这个字段是服务器用来通知客户端其所能接受的方法,当服务器收到不支持的HTTP方法的时候,就会以状态码405 Method Not Allowed作为响应返回,与此同时,还会把所有能支持的HTTP方法写进首部字段Allow后返回。
2、Content-Encoding
这个字段是服务器告诉客户端对实体部分的主体部分选用的内容编码方式,内容编码是只在不丢失实体信息的前提下所进行的压缩。
3、Content-Language
这个字段输用来告诉客户端,实体主体适用的语言(如中文或者英文等)
4、Content-Length
这个字段表示了实体主体部分的大小(单位是字节)
5、Content-Location
这个字段给出与报文主体部分相对应的URI
如
Content-Location: http://www.hackr.jp/index-ja.html
6、Content-MD5
客户端会对接收的报文主体执行相同的MD5算法,然后与首部字段Content-MD5字段值进行比较。
这个字段值是一串有MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
7、Content-Range
只对范围请求,返回响应是使用的首部字段,能告知客户端作为响应返回的实体的那个部分符合范围请求,字段值以字节为单位,表示当前发送部分及整个实体大小。
8、Content-Type
说明了实体猪体内对象的媒体类型和首部字段Accept一样。
9、Expires
这个字段会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求。在Expires字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。当服务器不希望缓存服务器对资源进行缓存的时候,最好在Expires字段内写入与首部字段Date相同的时间值。
Expires: Wed, 04 Jul 2012 08:26:05 GMT
10、Last-Modified
这个字段指明资源最后修改的时间,
(五)、跟Cookie相关的首部字段
1、Set-Cookie
开始状态管理所使用的Cookie信息,响应中的
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31
Set-Cookie中的一些字段
属性 |
说明 |
NAME=VALUE |
赋予Cookie的名称和其值 |
expires=DATE |
Cookie的有效期(若不明确指定,则默认为浏览器关闭前为止)。 需要注意的是,一旦Cookie被创建并被传输给客户端,那么服务器端则不能显示删除此Cookie,只能覆盖它 |
path=PATH |
将服务器上的文件目录作为Cookie的使用对象,若不指定则默认为文档所在的文件目录 |
domain=域名 |
作为Cookie适用兑现的域名(若 不指定则默认为创建Cookie的服务器的域名) |
Secure |
仅在HTTPS的情况下才会发送Cookie |
HttpOnly |
加以限制,使Cookie不会被js脚本访问 |
2、Cookie
服务器接收到的Cookie信息,当客户端想获得HTTP的状态管理支持的时候,就会在请求中包含从服务器接收到的Cookie
Cookie: status=enable
六、HTTPS
1,HTTP的缺点
通信使用明文(不加密),内容可能会被窃听
不验证通信方的身份
无法验证报文的完整性
2、为了防止被窃听,需要将通信进行加密,需要注意的是,即使被加密了,加密后的报文仍然可以被抓包到。
3、加密方法
将通信加密,通过和SSL(安全套接层)(HTTPS) 或者TLS(安全层传输协议)的组合使用,加密HTTP的通信内容。
使用SSL简历安全通信线路之后,就可以在这条路上进行HTTP通信了。
将内容加密
这种情况下,客户端需要对HTTP报文进行加密处理后再发送请求,这就需要客户端和服务器端具备同样的加密解密机制。因为这不是对线路济宁加密处理,所以内容仍有被篡改的风险。
3、因为HTTP中的request和response都不会对通信方进行确认,也就是说返回来的response有可能不是我们要的情况。这是因为任何人都可以发起请求,此外服务器只要接收到请求,就会给出一个response(ip和端口没有限定的情况下)
SSL提供了一种证书的手段,可以用于确定方。证书是用于证明服务器和客户端是实际存在的,只要能够确认客户端或服务端持有的证书,即可判断通信方的真实意图。
4、HTTP无法证明报文完整性
所谓完整性就是指信息的准确度,这样接收到的内容就有可能有误。也就是说,发送出去的request和response,是没有办法证明和接收到的是一致的。
6、HTTP+加密+认证+完整性保护 = HTTPS
7、HTTPS是身披着SSL外壳的HTTP
HTTP先跟SSL进行通信然后再跟TCP进行通信。
8、SSL的加密方法
共享密钥加密方法
SSL采用的是一种叫公开密钥加密的处理方法,也叫对称密钥加密,也就是加密和解密同用一个密钥。
使用一堆非对称的密钥,一把叫做私有密钥,另一把叫做公开密钥,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。
使用公开密钥加密方式,发送秘闻的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。
9、HTTPS的加密机制。
HTTPS采用共享密钥和公开密钥两者混合加密机制。
10、证明公开密钥本身是正确的公开密钥的方法:使用由数字证书认证机构和其相关机关颁发的公开密钥证书。
11、HTTPS的安全通信机制
第一步,客户端通过发送ClientHello报文开始SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件列表(所使用的的加密算法及密钥长度)
服务器可进行SSL通信的时候,会以Server Hello报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接受到的客户端加密组件内筛选出来的。
之后服务器发送Certificate报文,报文中包含公开密钥证书
最后服务器发送Server Hello Done 报文通知客户端,最初的SSL握手结束
SSL第一次握手结束之后,客户端以Client Key Exchange报文作为回应。报文中包含通信加密中使用的Pre-master随机密码串,该报文已经使用第三部中的公开密钥进行加密
接着客户端继续发送ChangeClipher Spec报文,该报文会提示服务器,在此报文之后的通信会采用刚刚Pre-master密钥加密。
客户端发送Finished报文。该报文包含链接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准
服务器同样发送ChangeClipher Spec报文
服务器同样发送Finished报文
服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成。之后的通信都会受到SSL的保护,开始发送HTTP请求。
应用层协议通信,HTTP响应
最后有客户端断开连接。断开连接时,发送close_notify报文。
TCP四次挥手。
七、认证机制
1、为了核对对方的身份,需要用到以下的信息
密码
动态令牌(仅限本人持有的设备内显示的一次性密码)
数字证书(仅限设备持有的信息)
生物认证
IC卡等
2、HTTP使用的认证方式
BASIC认证
DIGEST认证
SSL客户端认证
FormBase认证
2.1 BASIC 认证(不常用)
当请求的资源需要BASIC认证的手,服务器会随状态码401Authorization Required,返回带WWW-Authenticate首部字段的响应。该字段内包含认证的方式计一安全域字符串
接收到状态码401的客户端为了通过BASIC认证,需要将用户ID以及密码发送给服务器。发送的字符串内容是由用户ID和密码构成两者中间以冒号连接后,再经过Base64编码处理
比如,用户ID为lwl,密码是lwl,连接起来就会形成lwl:lwl这样的字符串。然后经过Base64编码,最后的字符串是bHdsOmx3bA==。把这个字符串写入首部字段Authorization之后,发送请求。(浏览器会自动编码并发送请求)
接收到包含首部字段Authorization请求的服务器,会对认证信息的正确性进行验证。如验证通过,则返回一条包含Request-URI字段的响应。
2.2 DIGEST认证
DIGEST认证同样适用质询/响应的方式,但不会像BASIC认证那样直接发送明文密码。
所谓质询方式是指,一开始一方会先发送认证要求给另一方,接着适用从另一方发送过来的质询码计算生成响应码,最后将响应码返回给对方进行认证的方式
DIGEST认证认证的步骤
请求需要认证的资源时,服务器会随着状态码为401,返回带WWW-Authenticate首部字段的响应,该字段内包含之响应方式认证所需的临时质询码(随机数)。首部字段 WWW-Authenticate 内必须包含 realm 和 nonce 这两个字段的信息。客户端就是依靠向服务器回送这两个值进行认证的。nonce 是一种每次随返回的 401 响应生成的任意随机字符串。该字符串通常推荐由 Base64 编码的十六进制数的组成形式,但实际内容依赖服务器的具体实现。
接收到401状态码的客户端,再次发送的request中包含DIGEST认证必须的首部字段Authorization信息。
再次接收到请求的服务器,会确认认证信息的增缺陷。认证通过后则返回包含资源的响应。
2.3 SSL客户端认证。
接收到需要认证资源的请求,服务器会放Certificate Request报文,要求客户端提供客户端证书。
用户选择将发送的客户端证书后,客户端会把客户端证书信息以Client Certificate报文方式发送给服务器
服务器验证客户端证书验证通过后方可领取证书内客户端的公开密钥,然后开始HTTPS加密通信。
SSL 客户端认证不会仅依靠证书完成认证,一般会和
基于表单认证(稍后讲解)组合形成一种双因素认证(Two-factor
authentication)来使用。所谓双因素认证就是指,认证过程中不仅需要密码这一个因素,还需要申请认证者提供其他持有信息,从而作为另一个因素,与其组合使用的认证方式。
换言之,第一个认证因素的 SSL 客户端证书用来认证客户端计算机,另一个认证因素的密码则用来确定这是用户本人的行为。
通过双因素认证后,就可以确认是用户本人正在使用匹配正确的计算机访问服务器
2.4、基于表单认证(常用)
基于表单认证本身是 通过服务器daunt的Web应用,将客户端发送过来的用户ID和密码与之前登陆过的信息做匹配进行认证的。因为HTTP无状态,因此使用Cookie来管理Session。
客户端将用户ID和密码等登陆信息放入报文的实体部分,通常是以POST方法把请求发送给服务器。而这时,会使用HTTPS通信来进行HTML表单画面的显示和用户输入数据的发送。
服务器会发送用以识别用户的Session ID。通过验证从客户端发送过来的登录信息进行身份验证,然后把用户的认证状态与Session ID绑定后记录在服务器端。向客户端返回响应时,会在首部字段 Set-Cookie 内写入 SessionID(如 PHPSESSID=028a8c…)Session ID 应使用难以推测的字符串,且服务器端也需要进行有效期的管理,保证其安全性。另外,为减轻跨站脚本攻击(XSS)造成的损失,建议事先在Cookie内加上 httponly 属性。
客户端接收到从服务器端发来的 Session ID 后,会将其作为Cookie 保存在本地。下次向服务器发送请求时,浏览器会自动发送Cookie,所以 Session ID 也随之发送到服务器。服务器端可通过验证接收到的 Session ID 识别用户和其认证状态
HTTP详解(更新完结)相关推荐
- Linux进程详解(二)完结
原创架构师之路2019-08-13 22:08 接Linux进程详解(一) 4. 进程运行 程序运行时大部分进程状态为运行或睡眠.调度算法解决可以跑的运行状态(就绪和运行),剩下的不可以跑的进程就是睡 ...
- LSTM反向传播详解(完结篇)Part3/3代码实现
1.前记 LSTM系列的前面两篇文章<LSTM反向传播详解Part1><LSTM反向传播详解Part2>将LSTM的理论梳理了一遍,本文主要着重用代码实现LSTM,其实也是 ...
- Ardupilot姿态控制详解(完结篇)
本文主要是对过去写的一些APM中姿态控制函数博文的汇总. 按照之前写的博文以及个人认为的学习顺序,给出APM姿态控制器的学习顺序如下: APM姿态旋转理论基础 Ardupilot姿态控制器 PID控制 ...
- Redis详解-更新中
目录 一.Redis 是什么 二.Redis 的特点和功能 三.Redis 缓存的使用 四.Redis 为什么能这么快 五.Redis 缓存的淘汰策略 六.Redis 持久化 1.为什么需要持久化 2 ...
- 适配iPhoneX全系详解,更新Xcode10爬坑
前言 熬夜看了WWDC2018, 为了坚决响应苹果号召, 迅速贯彻落实iOS12的新系统, 公司组织决定让我作为一个排头兵, 更新Xcode10, 看看苹果的新思想, 新作为. 更新Xcode10带来 ...
- Android空间架构与自定义控件详解-更新中
概述: 控件是每个Adnroid APP都必不可少的一部分,无论是使用系统控件还是使用自定义控件.这些控件组成了精美的界面. 本章将讲解Android控件架构,以及如何实现自定义控件. 本章你讲了解到 ...
- .NET 异步详解(更新)
前言 博客园(cnblogs.com)中有很多关于 .NET async/await 的介绍,但是很遗憾,很少有正确的,甚至说大多都是"从现象编原理"都不过分. 最典型的比如通过前 ...
- IEEE-754单精度浮点类型详解(完结篇)
IEEE-754工业标准 前言 众所周知,计算机内部系统实际只能存储二进制数据,我们在计算机中所使用到的文档.图片.影音等数据,实际都是以二进制的数据形式存放在计算机的内存或者硬盘中,不管内存(内存条 ...
- Block详解------已完结
1.Block的使用 Block是什么? 块,封装了函数调用以及调用环境的OC对象, Block的声明 //1. @property (nonatomic, copy) void(^myBlock1) ...
- chisel常见数据类型详解(更新)
主体内容摘自:https://blog.csdn.net/qq_34291505/article/details/87570908 一.Chisel的数据类型 Chisel定义了自己的一套数据类型,读 ...
最新文章
- keras/tensorflow 模型保存后重新加载准确率为0 model.save and load giving different result
- 理解标准输出流方法:WriteLine和Write
- java调用kettle连hive_使用java连接hive,并执行hive语句详解
- java.util.List学习笔记
- linux基本操作之目录、vi等
- Linux服务器rsync自动备份
- primefaces_通过OmniFaces缓存组件以编程方式缓存PrimeFaces图表
- js html 导出word 不用activexobject,javascript下用ActiveXObject控件替换word书签,将内容导出到word后打印第2/2页...
- LLVM每日谈之十二 LLVM的源码分析之Pass相关
- js和jQuery 获取屏幕高度、宽度
- 今天的不是陶渊明的 飞鸽传书
- 正则表达式【第二卷】
- docker相关配置
- MVC+EF 入门教程(四)
- 设计模式(外观模式)
- 2010年及以前的微博
- 15亿参数的NLP模型究竟有多强大?有人用它生成了一部《哈利·波特》
- Go语言path is relative, but relative import paths are not supported in module mode
- Ubuntu 桌面美化: 1.命令行terminal显示时间用户conda环境2.桌面自动更换轮换壁纸Bing Wallpaper
- 02:产品常用工具及网站