概念及常识
HTTP (Hypertext transfer protocol)
- 超文本传输协议;
- 详细规定了浏览器和万维网服务器之间通信的规则;
- 浏览器变得更加高效,传输字节变少;
- 工作在应用层,是无状态协议,由请求和响应两部分组成;
- HTTP默认端口是80;
- HTTPS默认端口是443;
HTTP协议通常承载于TCP协议之上;有时也承载于TLS或SSL协议层之上,也就是我们常说的HTTPS。
大部分网站采用HTTP协议进行交互,目前仍有大量的客户端采用HTTP协议进行交互。但是随着安全等级的提升,这些交互逐渐被HTTPS协议取代;
请求的流程
一次HTTP操作称为一个事务,其工作过程可分为五步:
- 1)客户端与服务器开始建立连接;
- 2)客户端发送一个请求给服务器,请求的格式为:URL(统一资源标识符)、协议版本号,后边是MIME信息包括请求修饰符、客户端信息及内容;
- 3)服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息及内容;
- 4)客户端接收服务器所返回的信息,进行对应处理;
- 5)客户端与服务器断开连接;
所有流程,均由HTTP请求自动完成。如果在以上过程中的某一步出现错误,那么产生错误的信息将返回,客户端做对应处理。可以是客户端直接与服务器进行交互,也可能在请求中间增加代理。
HTTP基于传输层TCP协议,而TCP是一个端到端的面向连接的协议。所谓的端到端可以理解为进程到进程之间的通信。所以HTTP在开始传输之前,首先需要建立TCP连接,而TCP连接的过程需要所谓的“三次握手”。盗用下图所示TCP连接的三次握手:
在TCP三次握手之后,TCP连接建立,此时HTTP就可以进行传输了。
在HTTP1.1中传输完成之后并不断开TCP连接,需要通过Connection头设置。
具体三次握手和四次挥手,可参考文章:https://www.cnblogs.com/Andya/p/7272462.html,非常详细。
HTTP协议特点
由于服务器的IP或者域名都是相对固定的,而客户端可能经常发生变化,因此HTTP协议似乎永远是客户端(Client)发起请求,服务器(Server)返回响应,Request和Response成对出现。同时,如果客户端没有主动请求,很难实现由服务端向客户端推送数据。
HTTP协议的主要特点可概括如下:
1、支持客户端/服务器模式,支持基本认证和安全认证。
2、简单快速
客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3、灵活
HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4、可以持续连接
HTTP 0.9和1.0使用非持续连接,限制每次连接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,即断开连接;HTTP 1.1使用持续连接,默认都开启了Keep-Alive,不必为每个web对象创建一个新的连接,一个连接可以传送多个对象,采用这种方式可以节省传输时间。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。
5、无状态
协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
请求格式及方法
格式
URL(Uniform Resource Locator)格式,http://www.xxxxxx.com/images/icon.png;
地址用于描述一个网络上的资源,使用协议+host+path的方式,基本格式如下:
schema://host[:port#]/path/.../[url-params]?[query-string][#fragment]
- scheme:使用的协议名称(如:http, https, ftp);
- host:服务器的IP地址或者域名;
- port:端口号,HTTP的默认端口是80,可以省略。如果使用了别的端口,必须指明,例如 > * http://www.xxxx.com:7000/;
- path:访问资源的路径;
- url-params:文件名称,后边用问好与参数分隔;
- query-string:各个参数的名称和具体值,用等号连接,多个键值对用‘&’进行分隔;
- fragment:网页中可能会分为不同的片段,如果想访问网页后直接到达指定位置,可以在这部分设置;
请求头参数
Accept
客户端可以接收的MIME类型。例如:Accept: text/html,表示接收服务器的文本;如果服务器无法返回text/html类型的数据,服务器会返回一个406错误(non acceptable)。平时可以使用Accept: / 代表浏览器可以处理所有类型。
Accept-Encoding
客户端声明可以接收的编码方式,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate);Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面,可以节省5到10倍的下载时间。例如: Accept-Encoding: gzip, deflate。如果请求消息中没有设置这个域,服务器默认客户端可以接收所有编码。
Accept-Language
声明自己接收的语言。语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等;例如:Accept-Language:en-us。如果请求消息中没有设置这个报头域,服务器假定客户端可以接收所有语言。
Accept-Charset
浏览器可接受的字符集。如果在请求消息中没有设置这个域,默认表示任何字符集都可以接受。
User-Agent
告诉服务器,客户端使用的操作系统和浏览器的名称和版本。
例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)。
Content-Type
例如:Content-Type: application/x-www-form-urlencoded。
Referer
包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。提供了Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的,主要用来统计访问来源。
例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT
Connection:
例如:Connection: keep-alive,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。HTTP 1.1默认进行持久连接。利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。
再比如:Connection:close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request,需要重新建立TCP连接。
Host
主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回。
Cookie
浏览器很常用由于HTTP请求没有状态,所以将cookie的值发送给HTTP服务器,许多广告的精准推荐就是这样来的。
Content-Length
表示请求消息正文的长度。例如:Content-Length: 13540,可以做消息是否完成的校验。
Authorization
授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中。主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证。
UA-Pixels,UA-Color,UA-OS,UA-CPU
由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和CPU类型。
Range
可以请求实体的一个或者多个子范围,下载文件的断点续传就是使用这个字段做的;例如:
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200(OK)
请求方式 - Request
HTTP/1.1协议,共定义了八种方法,用来表明Request-URI指定的资源的不同操作方式:
GET
向特定的资源发出“获取”请求。GET方法最好只用于获取数据,不修改服务器的任何信息;GET方法多会将参数拼接在url的后端,相当于明文传输,因此不要使用该方法传递任何敏感信息;GET最大字节数为1024。
POST
向指定资源提交数据进行处理请求,提交表单或者上传文件。数据被包含在请求体中;POST请求可能会导致新的资源的建立或已有资源的修改。
PUT
向指定资源位置上传其最新内容。
DELETE
请求服务器删除Request-URI所标识的资源。
OPTIONS
返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送'*'的请求来测试服务器的功能性。
HEAD
向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新。
TRACE
回显服务器收到的请求,主要用于测试或诊断。
CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
PATCH
用来将局部修改应用于某一资源,添加于规范RFC5789。
方法名称区分大小写。当某个请求所针对的资源不支持对应的请求方法的时候,服务器返回状态码405(Method Not Allowed);当服务器不认识或者不支持对应的请求方法的时候,应当返回状态码501(Not Implemented)。
HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。此外,除了上述方法,特定的HTTP服务器还能够扩展自定义的方法。
响应消息 - Response
包含:状态行、消息报头、响应正文。
每一次请求,都会产生一个响应。一般使用状态码,粗略区分请求是否成功。如果一切正常,一个标准网页会收到一条200的状态码;错误有对应的错误码,常见的有403、404、500等。
下面列出所有错误码:
以1开头:表示接收到请求并且继续处理
- 100 - 客户必须继续发出请求
- 101 - 客户要求服务器根据请求转换HTTP协议版本
以2开头:表示动作被成功接收、理解和接受,一般可理解为响应成功
- 200 - 表明该请求被成功地完成,所请求的资源发送回客户端
- 201 - 提示知道新文件的URL
- 202 - 接受和处理、但处理未完成
- 203 - 返回信息不确定或不完整
- 204 - 请求收到,但返回信息为空
- 205 - 服务器完成了请求,用户代理必须复位当前已经浏览过的文件
- 206 - 服务器已经完成了部分用户的GET请求
以3开头:为了完成指定的动作,必须接受进一步处理,即重定向
- 300 - 请求的资源可在多处得到
- 301 - 本网页被永久性转移到另一个URL
- 302 - 请求的网页被转移到一个新的地址,但客户访问仍继续通过原始URL地址,重定向,新的URL会在response中的Location中返回,浏览器将会使用新的URL发出新的Request。
- 303 - 建议客户访问其他URL或访问方式
- 304 - 自从上次请求后,请求的网页未修改过,服务器返回此响应时,不会返回网页内容,代表上次的文档已经被缓存了,还可以继续使用
- 305 - 请求的资源必须从服务器指定的地址得到
- 306 - 前一版本HTTP中使用的代码,现行版本中不再使用
- 307 - 申明请求的资源临时性删除
以4开头:请求包含错误语法或不能正确执行
- 400 - 客户端请求有语法错误,不能被服务器所理解
- 401 - 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
- HTTP 401.1 - 未授权:登录失败
- HTTP 401.2 - 未授权:服务器配置问题导致登录失败
- HTTP 401.3 - ACL 禁止访问资源
- HTTP 401.4 - 未授权:授权被筛选器拒绝
- HTTP 401.5 - 未授权:ISAPI 或 CGI 授权失败
- 402 - 保留有效ChargeTo头响应
- 403 - 禁止访问,服务器收到请求,但是拒绝提供服务
- HTTP 403.1 - 禁止访问:禁止可执行访问
- HTTP 403.2 - 禁止访问:禁止读访问
- HTTP 403.3 - 禁止访问:禁止写访问
- HTTP 403.4 - 禁止访问:要求 SSL
- HTTP 403.5 - 禁止访问:要求 SSL 128
- HTTP 403.6 - 禁止访问:IP 地址被拒绝
- HTTP 403.7 - 禁止访问:要求客户证书
- HTTP 403.8 - 禁止访问:禁止站点访问
- HTTP 403.9 - 禁止访问:连接的用户过多
- HTTP 403.10 - 禁止访问:配置无效
- HTTP 403.11 - 禁止访问:密码更改
- HTTP 403.12 - 禁止访问:映射器拒绝访问
- HTTP 403.13 - 禁止访问:客户证书已被吊销
- HTTP 403.15 - 禁止访问:客户访问许可过多
- HTTP 403.16 - 禁止访问:客户证书不可信或者无效
- HTTP 403.17 - 禁止访问:客户证书已经到期或者尚未生效
- 404 - 一个404错误表明可连接服务器,但服务器无法取得所请求的网页,请求资源不存在。eg:输入了错误的URL
- 405 - 用户在Request-Line字段定义的方法不允许
- 406 - 根据用户发送的Accept拖,请求资源不可访问
- 407 - 类似401,用户必须首先在代理服务器上得到授权
- 408 - 客户端没有在用户指定的饿时间内完成请求
- 409 - 对当前资源状态,请求不能完成
- 410 - 服务器上不再有此资源且无进一步的参考地址
- 411 - 服务器拒绝用户定义的Content-Length属性请求
- 412 - 一个或多个请求头字段在当前请求中错误
- 413 - 请求的资源大于服务器允许的大小
- 414 - 请求的资源URL长于服务器允许的长度
- 415 - 请求资源不支持请求项目格式
- 416 - 请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
- 417 - 服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求长。
以5开头:服务器不能正确执行一个正确的请求,一般都为服务器错误
- HTTP 500 - 服务器遇到错误,无法完成请求
- HTTP 500.100 - 内部服务器错误 - ASP 错误
- HTTP 500-11 服务器关闭
- HTTP 500-12 应用程序重新启动
- HTTP 500-13 - 服务器太忙
- HTTP 500-14 - 应用程序无效
- HTTP 500-15 - 不允许请求 global.asa
- Error 501 - 未实现
- HTTP 502 - 网关错误
- HTTP 503:由于超载或停机维护,服务器目前无法使用,一段时间后可能恢复正常
发现了一个趣味状态码图,喜欢可以点击:https://www.toutiao.com/i6628119994469204484/
响应头参数
Allow
服务器支持哪些请求方法(如GET、POST等)。
Date
表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦
Expires
指明应该在什么时候认为文档已经过期,从而不再缓存它,重新从服务器获取,会更新缓存。过期之前使用本地缓存。HTTP1.1的客户端和缓存会将非法的日期格式(包括0)看作已经过期。eg:为了让浏览器不要缓存页面,我们也可以将Expires实体报头域,设置为0。
例如: Expires: Tue, 08 Feb 2022 11:35:14 GMT
P3P
用于跨域设置Cookie, 这样可以解决iframe跨域访问cookie的问题
例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR
Set-Cookie
非常重要的header, 用于把cookie发送到客户端浏览器,每一个写入cookie都会生成一个Set-Cookie。
例如: Set-Cookie: sc=4c31523a; path=/; domain=.acookie.taobao.com
ETag
和If-None-Match 配合使用。
Last-Modified
用于指示资源的最后修改日期和时间。Last-Modified也可用setDateHeader方法来设置。
Content-Type
WEB服务器告诉浏览器自己响应的对象的类型和字符集。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。可在web.xml文件中配置扩展名和MIME类型的对应关系。
例如:Content-Type: text/html;charset=utf-8
Content-Type:text/html;charset=GB2312
Content-Type: image/jpeg
媒体类型的格式为:大类/小类,比如text/html。
IANA(The Internet Assigned Numbers Authority,互联网数字分配机构)定义了8个大类的媒体类型,分别是:
- application,比如: application/vnd.ms-excel.
- audio,比如: audio/mpeg.
- image,比如: image/png.
- message,比如,:message/http.
- model,比如:model/vrml.
- multipart,比如:multipart/form-data.
- text,比如:text/html.
- video,比如:video/quicktime.
Content-Range
用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-length。
例如,传送头500个字节次字段的形式:Content-Range:bytes0-499/1234如果一个http消息包含此节(例如,对范围请求的响 应或对一系列范围的重叠请求),Content-Range表示传送的范围。
Content-Length
指明实体正文的长度,以字节方式存储的十进制数字来表示。在数据下行的过程中,Content-Length的方式要预先在服务器中缓存所有数据,然后所有数据再一股脑儿地发给客户端。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入ByteArrayOutputStram,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。
例如: Content-Length: 29837
Content-Encoding
WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。
例如:Content-Encoding:gzip
Content-Language
WEB服务器告诉浏览器自己响应的对象所用的自然语言。
例如: Content-Language:da。没有设置该域则认为实体内容将提供给所有的语言阅读。
Server
指明HTTP服务器用来处理请求的软件信息。
例如:Server: Microsoft-IIS/7.5、Server:Apache-Coyote/1.1。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。
X-AspNet-Version
如果网站是用ASP.NET开发的,这个header用来表示ASP.NET的版本。
例如: X-AspNet-Version: 4.0.30319
X-Powered-By
表示网站是用什么技术开发的。
例如:X-Powered-By: ASP.NET
Connection
例如:
Connection: keep-alive,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
Connection: close,代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request,需要重新建立TCP连接。
Location
用于重定向一个新的位置,包含新的URL地址。表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。Location响应报头域常用在更换域名的时候。
Refresh
表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。注意Refresh的意义是“N秒之后刷新本页面或访问指定页面”,而不是“每隔N秒刷新本页面或访问指定页面”。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV="Refresh" ...>。注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。
HTTPS
HTTPS
Hypertext Transfer Protocol over Secure Socket Layer,是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入TLS层,HTTPS的安全基础是TLS。
SSL
Secure Socket Layer,安全套接字层,1994年为 Netscape 所研发,SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持,目前逐渐废弃了。
TLS
Transport Layer Security,传输层安全,其前身是 SSL,它最初的几个版本(SSL 1.0、SSL 2.0、SSL 3.0)由网景公司开发,1999年从 3.1 开始被 IETF 标准化并改名,发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。SSL3.0和TLS1.0由于存在安全漏洞,已经很少被使用到。TLS 1.3 改动会比较大,目前还在草案阶段,目前使用最广泛的是TLS 1.1、TLS 1.2。
两种加密算法
对称加密
密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等。
非对称加密
密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。
证书包括内容:
- (1)证书的发布机构CA
- (2)证书的有效期
- (3)公钥
- (4)证书所有者
- (5)签名
客户端在接受到服务端发来的SSL证书时,会对证书的真伪进行校验,以浏览器为例说明如下:
- (1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验
- (2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发
所以通过发送SSL证书的形式,既解决了公钥获取问题,又解决了黑客冒充问题,一箭双雕,HTTPS加密过程也就此形成
所以相比HTTP,HTTPS 传输更加安全
- (1) 所有信息都是加密传播,黑客无法窃听。
- (2) 具有校验机制,一旦被篡改,通信双方会立刻发现。
- (3) 配备身份证书,防止身份被冒充。
HTTPS 缺点:
- SSL 证书费用很高,以及其在服务器上的部署、更新维护非常繁琐
- HTTPS 降低用户访问速度(多次握手)
- 网站改用HTTPS 以后,由HTTP 跳转到 HTTPS 的方式增加了用户访问耗时(多数网站采用302跳转)
- HTTPS 涉及到的安全算法会消耗 CPU 资源,需要增加大量机器(https访问过程需要加解密)
- 如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。
- 如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密
- 浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比
- 对比结果一致,则证明服务器发来的证书合法,没有被冒充
- 此时浏览器就可以读取证书中的公钥,用于后续加密了
综上所述,相比 HTTP 协议,HTTPS 协议增加了很多交互、加密解密等流程,保证数据传输的安全,很大程度上避免了黑客的攻击。