计算机网络(二)--HTTP详解
Web相关内容都是存储在Web服务器上,Web服务器上使用的是http协议,因此也被成为http服务器。http的client、server构成了万维网的
基本组件
一、资源
1、URI:
统一资源标识符,http通过给定的URI解析出对象。URI有两种形式:URL/URN
2、URL:
统一资源定位符,描述一台服务器上某资源的特定位置。可以明确说明如何从一个精确、固定的位置获取资源
例如:http://www.oreilly.com/index.html
PS:几乎所有的URI都是URL
3、URN:
统一资源名,与目前的资源所在地无关。使用URN,可以随意修改资源位置。URN一般使用较少
二、HTTP方法
1).Get:
获取资源
2).Post:
用来传输实体主体
Get和Post都可以用来传输实体的主体和获取响应的主体内容,但是一般通过Post负责前者,Get负责后者
3).Put:
请求用来传输文件,就像 FTP 协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求 URI 指定的位置。但是,
HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件, 存在安全性问题,因此一般的 Web 网站不使用该方法。若配合 Web 应用程序的
验证机制,或架构设计采用REST标准的同类Web 网站,就可能会开放使用 PUT 方法。
4).Head:
HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URI的有效性及资源更新的日期时间等。
5).DELETE:
用来删除文件,与PUT相反。DELETE方法按请求URI删除指定的资源。和Put相同,自身不带验证机制,也要满足两个条件
6).OPTIONS:
用来查询针对请求URI指定的资源支持的方法。
三、HTTP报文
HTTP 报文是在 HTTP 应用程序之间发送的数据块。每条报文都包含一条来自客户端的请求,或者一条来自服务器的响应。它们由三个部分组
成:对报文进行描述的起始行(start line)、包含属性的首部(header)块,以及包含数据的主体(body,可选)部分。
1、首部字段
通常分为:通用首部、请求首部、响应首部和实体首部、Cookie等
2、编码提高传输效率
HTTP报文可以直接按原样传输,也可以通过编码提高传输效率,但是编码会消耗更多的CPU资源
2.1).报文主体和实体主体的差异
报文(message):
是HTTP通信中的基本单位,由8位组字节流组成,通过HTTP通信传输。
实体(entity):
作为请求或响应的有效承载数据被传输,其内容由实体首部和实体主体组成。
PS:HTTP报文的主体用于传输请求或响应的实体主体。通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体主体的内容发生
变化,才导致它和报文主体产生差异。报文和实体这两个术语在之后会经常出现,请事先理解两者的差异。
2.2).压缩传输的内容编码
内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。
常用的内容编码:
1、gzip(GNU zip)
2、compress(UNIX 系统的标准压缩)
3、deflate(zlib)
4、identity(不进行编码)
2.3).分割发送的分块传输编码
在 HTTP 通信过程中,请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。在传输大容量数据时,通过把数据分割成
多块,能够让浏览器逐步显示页面。这种把实体主体分块的功能称为分块传输编码(Chunked TransferCoding)。
四、HTTP报文首部
HTTP 协议的请求和响应报文中必定包含HTTP首部
HTTP请求报文:在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。
HTTP响应报文:在响应中,HTTP报文由 HTTP版本、状态码(数字和原因短语)、HTTP首部字段 3 部分构成。
1、通用首部字段
1).Cache-Control
用来控制缓存行为,指令是可选的,通过逗号分隔
例如:响应指令Cache-Control: private, max-age=0, no-cache
缓存请求指令:
缓存响应指令:
2).Connection作用:
1).控制不再转发给代理的首部字段
例如:Connection:Upgrade
2).管理持久连接
Connection:close 断开连接
Connection:Keep-Alive 持久化连接
3).Date:
表明创建 HTTP 报文的日期和时间,时间表示分为三种:
1、HTTP/1.1版本:Date: Tue, 03 Jul 2012 04:40:59 GMT
2、HTTP/1.1之前的版本:Date: Tue, 03-Jul-12 04:40:59 GMT
3、第三种:Date: Tue Jul 03 04:40:59 2012
4).Pragma:
Pragma是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。
规范定义的形式唯一:Pragma: no-cache
该首部字段属于通用首部字段,但只用在客户端发送的请求中。
发送的请求会同时含有下面两个首部字段。
Cache-Control: no-cache 如果所有的中间服务器都能以 HTTP/1.1为基准,这只是理论上,实际情况还是需要这两个字段
Pragma: no-cache
2、请求首部字段
1、Accept
可通知服务器、用户代理能够处理的媒体类型以及其相对优先级。可使用type/subtype这种形式,一次指定多种媒体类型。
例如:Accept: text/html,application/xhtml+xml,application/xml;q=0
举例:
1).文本文件
text/html, text/plain, text/css ...
application/xhtml+xml, application/xml ...
2).图片文件
image/jpeg, image/gif, image/png ...
3).视频文件
video/mpeg, video/quicktime ...
4).应用程序使用的二进制文件
application/octet-stream, application/zip
增加优先级:用分号;进行分隔。权重值 q 的范围是 0~1(可精确到小数点后3位),且1为最大值。不指定权重q值时,默认权重为q=1.0。
2、Accept-Charset
用来通知服务器用户代理支持的字符集以及其相对优先级。可一次性指定多种字符集。也可以用权重q值来表示相对优先级。
例如:Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
3、Accept-Encoding
Accept-Encoding 首部字段用来告知服务器用户代理支持的内容编码以及其优先级顺序。可一次性指定多种内容编码。
例如:Accept-Encoding: gzip, deflate
举例:
1).gzip
由文件压缩程序gzip(GNU zip)生成的编码格式(RFC1952),采用 Lempel-Ziv算法(LZ77)及32位循环冗余校验(统称CRC)
2).compress
由UNIX文件压缩程序compress生成的编码格式,采用Lempel-Ziv-Welch 算法(LZW)。deflate组合使用 zlib 格式(RFC1950)及由
deflate 压缩算法(RFC1951)生成的编码格式。
3).identity
不执行压缩或不会变化的默认编码格式采用权重 q 值来表示相对优先级。也可使用星号(*)作为通配符,指定任意的编码格式。
4、Accept-Language
用来告知服务器用户代理能够处理的自然语言集(中文或英文等),以及自然语言集的相对优先级。可一次指定多种自然语言集。可按权重值
q 来表示相对优先级。
例如:Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3
5、Authorization
用来告知服务器,用户代理的认证信息(证书值)。通常,接收到返回的401状态码响应后,把首部字段 Authorization 加入请求中。
共用缓存在接收到含有 Authorization 首部字段的请求时的操作处理会略有差异。
例如:Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
6、Expect
用来告知服务器,期望出现的某种特定行为。返回417状态码时,客户端可以利用该首部字段,写明所期望的扩展。虽然HTTP/1.1规范只定义
了100-continue(状态码 100 Continue)。
等待状态码100响应的客户端在发生请求时,需要指定 Expect:100-continue。
7、From
用来告知服务器使用用户代理的用户的电子邮件地址。通常,其使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。
使用代理时,应尽可能包含 From 首部字段(但可能会因代理不同,将电子邮件地址记录在 User-Agent 首部字段内)。
8、If-Match
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
只有当 If-Match 的字段值跟 ETag 值匹配一致时,服务器才会接受请求,否则返回状态码 412 Precondition Failed 的响应
If-Match:*,服务器会忽略ETag
9、If-Modified-Since
例如:If-Modified-Since: Thu, 15 Apr 2004 00:00:00 GMT
如果在 If-Modified-Since 字段指定的日期时间后,资源发生了更新,服务器会接受请求。否则返回304 Not Modified
用于确认代理或客户端拥有的本地资源的有效性获取资源的更新日期时间,可通过确认首部字段 Last-Modified 来来确定
10、If-None-Match
在 If-None-Match 的字段值与 ETag 值不一致时,可处理该请求。与 If-Match 首部字段的作用相反
在 GET 或 HEAD 方法中使用首部字段 If-None-Match 可获取最新的资源
3、响应首部字段
ETag:
例如:ETag: "82e22293907ce725faf67773957acd12"
首部字段 ETag 能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag值。
当资源更新时,ETag 值也需要更新
4、实体首部字段
五、状态码
每条 HTTP 响应报文返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是否需要采取其他动作。
1、2XX成功
1.1).200 OK:
表示请求被服务器正常处理了
1.2).204 No Content:
服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分,也不允许返回任何实体的主体。
PS:当从浏览器发出请求处理后,返回 204 响应,那么浏览器显示的页面不发生更新。
使用场景:一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。
1.3).206 Partial Content:
该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET 请求。
2、3XX重定向
2.1).301:
永久性重定向
2.2).302:
临时性重定向
3、4XX客户端错误
3.1).400 Bad Request
该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。
3.2).401 Unauthorized
发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示用户认证失败。
3.3).403 Forbidden
对请求资源的访问被服务器拒绝了
3.4).404 Not Found
服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。
4、5XX 服务器错误
4.1).500 Internal Server Error
服务器端在执行请求时发生了错误。也有可能是 Web应用存在的 bug 或某些临时的故障。
4.2).503 Service UnvUnavailable
服务器暂时处于超负载或正在进行停机维护,现在无法处理请求
PS:
不少返回的状态码响应都是错误的,但是用户可能察觉不到这点。比如 Web 应用程序内部发生错误,状态码依然返回200 OK,这种情况也
可能遇到。
六、连接
HTTP是应用层协议。无需操心网络通信的具体细节。它把联网的细节都交给了通用、可靠的互联网传输协议 TCP/IP
在TCP/IP四层协议中,HTTP报文每经过一层就会加上一层的首部,接收端,从下往上每经过一层删除首部,也就是封装
发送端:
1、应用层:client发送一个HTTP请求
2、传输层:从应用层处收到的http请求报文进行分割,在各个报文上打上标记序号及端口号后转发给网络层
3、网络层:增加作为通信目的地的MAC地址后转发给链路层。这时候,发送网络的通信请求就准备齐全了
接收端:从链路层到最上面应用层,才是真正收到HTTP请求
HTTP无状态:
不保存请求和相应的信息,也就是不做持久化处理,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或
响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。
HTTP无连接:
最开始HTTP1.0之前的版本是无连接的,发送一个请求,得到相应,就会断开连接,下次发送重新奖励连接。HTTP1.1和部分HTTP1.0开始支持
keep-alive,只要任意一端不主动断开,会一直保持TCP连接
七、Cookie
Http无状态是很高效,但是带来很多问题,最典型的就是一个网站的登录状态问题,不可能每个网页都要登陆一次,为了解决这个问题,引入了
Cookie。Cookie+HTTP就可以管理状态了
根据Response报文的Set-Cookie首部字段,通知客户端保存Cookie。下次client发送报文就会带有Cookie
例如:Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31
1、expires:
当省略expires属性,默认有效期到浏览器关闭之前
2、secure:
用于限制Web页面只有在HTTPS安全连接时,才可以发送Cookie
例如:Set-Cookie: name=value; secure
3、HttpOnly:
这是Cookie的扩展功能。它使JavaScript脚本无法获得 Cookie。其主要目的为防止跨站脚本攻击(Cross-sitescripting,XSS)对Cookie的信息窃取
例如:Set-Cookie: name=value; HttpOnly
这时候document.cookie就无法读取附加HttpOnly属性后的Cookie的内容了。因此,也就无法在XSS中利用JavaScript劫持Cookie了
4、Cookie:
例如:Cookie: status=enable
告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式发送
5、pipeline:
不用等待响应就可以直接发送下一次请求,就可以并行发送多个请求。
八、其他首部字段
HTTP 首部字段是可以自行扩展的。所以在Web服务器和浏览器的应用上,会出现各种非标准的首部字段
1、X-Frame-Options
属于HTTP响应首部,用于控制网站内容在其他 Web 网站的Frame标签内的显示问题。其主要目的是为了防止点击劫持clickjacking攻击
例如:X-Frame-Options: DENY
有两个取值:
1、DENY:拒绝
2、SAMEORIGIN:仅同源域名下的页面匹配时许可。
比如,当指定 http://hackr.jp/sample.html页面为SAMEORIGIN 时,那么 hackr.jp 上所有页面的 frame 都被允许可加载该页面,其它域名不可以
PS:主流的浏览器都支持
2、X-XSS-Protection
属于HTTP响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关
可指定的字段值如下:
0 :将XSS过滤设置成无效状态
1 :将XSS过滤设置成有效状态
例如:X-XSS-Protection: 1
3、DNT:Do Not Track
属于HTTP请求首部,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法
可指定的字段值如下
0 :同意被追踪
1 :拒绝被追踪
由于首部字段 DNT 的功能具备有效性,所以 Web 服务器需要对 DNT做对应的支持
九、跨域
当发生跨域的时候,如果response的header没有Access-Control-Allow-Origin参数,就会发生报错,实际上client不知道有没有这个参数,
请求也已经发送了,只是返回的时候发现没有这个参数,所以报错拦截了,这只是浏览器的同域限制,如果浏览器没有这个限制,也就谈不上
跨域了。
解决方案:
1、Access-Control-Allow-Origin:*:
所有的网站都可以访问,或者设置为某个域名,就只有这个域名可以访问
2、jsonp实现跨域,例如<script src="URL"></script>,这时候不会报错,浏览器对于link、script等标签是允许发生跨域的
十、HTTP缺点
1、通信使用明文(不加密),内容可能会被窃听
按照TCP/IP协议通信,通信内容是可能遭到窃听的,可以通过抓包工具收集数据包分析数据
1).通信加密:通过和SSL或TLS组合使用,加密HTTP的通信路线,建立安全的通信通道
2).内容加密:将通信内容本身进行加密,报文头部不进行加密,报文主体内容进行加密,要求客户端和服务端具有进行加密和解密机制,不同
于通信加密的方式,内容还是有可能被篡改
2、不验证通信方的身份,因此有可能遭遇伪装
HTTP 协议中的请求和响应不会对通信方进行确认,任何人都可发起请求,服务端和客户端可能都是伪装的,无法确定双方是不是具有访问权限
,通过SSL中证书来验证身份,证书是由相关第三方机构颁发
3、无法证明报文的完整性,所以有可能已遭篡改
完整性是指信息的准确性,请求或响应在传输途中,遭攻击者拦截并篡改内容的攻击称为中间人攻击,虽然有使用 HTTP 协议确定报文完整性的
方法,但事实上并不便捷、可靠。其中常用的是 MD5 和 SHA-1 等散列值校验的方法,以及用来确认文件的数字签名方法。
所以就需要HTTPS,HTTPS = HTTP + 通信加密 + 证书 + 完整性保护,不光是HTTP,其它在应用层的协议例如SMTP、Telnet等都可以配合SSL使用
,SSL使用公钥进行加密
SSL:
Security Socket Layer,为网络通信提供安全以及数据完整性的一种安全协议
是操作系统对外提供的API,SSL3.0之后更名为TLS
采用身份认证和数据加密保证网络通信安全以及数据完整性
加密方式:
对称加密:加密和解密是同一个密钥
非对称加密:加密使用公钥,解密使用私钥,性能相对对称加密较低,但是安全性很高
Hash算法:将信息转换为hash,过程不可逆
数字签名:在信息后加上一个签名,来证明消息和文件是某人发出的,没有被修改过
HTTPS数据传输过程:
1、Browser将支持的加密算法发送给Server
2、Server选择一套Browser支持的加密算法,以证书的形式返回给浏览器
3、Browser验证证书的合法性,并且结合证书的公钥加密信息发送给Server端
4、Server端使用私钥进行解密,验证Hash,加密响应信息返回给Client端
5、Browser加密响应信息,对消息进行验证,之后进行加密交互数据
HTTP和HTTPS的区别:
1、HTTPS需要CA申请证书,HTTP不需要
2、HTTPS密文传输,HTTP明文传输
3、连接方式不通,HTTP默认80端口,HTTPS默认443端口
4、HTTPS = HTTP + 通信加密 + 证书 + 完整性保护,相对HTTP更加安全
在浏览器输入URL,按下回车之后的流程:
1、DNS解析:
根据URL逐层查询到DNS服务器缓存,解析URL的域名对应的IP地址,DNS缓存分别为:浏览器缓存、系统缓存、路由器缓存、服务器缓存、域名
服务器缓存、顶级域名服务器缓存,从前到后找到立刻返回,不会继续查询。
2、TCP连接:
根据IP和port和服务器建立TCP连接,三次握手的过程
3、浏览器发送HTTP请求
4、服务器处理请求并返回HTTP报文
5、浏览器收到请求报文,并渲染页面
6、释放连接,也就是四次挥手的过程
PS:第五步和第六步没有前后顺序
GET和POST的区别:
1、HTTP报文层面:
GET请求会把请求信息放到URL后面,以?隔开,POST放到报文体内,安全性没啥区别,GET可以直接看到参数,POST只要抓包还是能看到
GET请求长度:
HTTP对URL请求没有限制,但是浏览器会做限制,而POST请求参数放到报文体,理论上没有限制
2、数据库层面
GET请求符合幂等性和安全性,POST不符合
3、其他方面
GET请求可以被缓存(大部分都被CDN缓存了)、存储,POST不行
Cookie和Session的区别:
因为HTTP无状态的特性,为了解决这个问题,有了cookie和session
Cookie:就是服务器发送给client的信息(Set-Cookie),以文本的方式保存在client,每次向server发送请求都会带上cookie
Cookie是保存在response的响应头和HTTP Request的head中,而不是响应体中
Session:Server端保存的信息,Client请求中包含session id,就会保存这个状态信息
Session实现方式:
1、Cookie:
Server返回Set-Cookie: JSESSIONID=XXXX,Client发送请求Cookie:JSESSIONID=XXXX
2、URL回写:每个URL都带有JSESSIONID
PS:Tomcat支持这两种方式,如果Cookie被禁用,就使用URL回写,否则使用Cookie的实现方式
分布式环境下可能更多的使用基于Token的方式,通过Redis进行存储
区别:
1、Cookie放在Browser,Session放在服务器
2、Session相对Cookie更安全,存在Cookie欺骗
3、如果需要减轻服务器负担,可以考虑Cookie
内容参考:图解HTTP+HTTP权威指南