http基础学习总结
# http学习研究
学习目标
1、理解域名解析的整个过程
2、理解 web 页面请求的整个流程,绘制流程图(nginx 处理的 11 个过程)
3、学习 http 协议中的字段及含义
4、学习 http 请求方法以及返回状态码的类型和含义
http基础知识
之前读过图解HTTP,那本书对新人还是挺友好的。正好这一关设计之前的知识,之前没有做笔记,零零散散的记不太清楚。于是趁着这一次,好好的复习一下。
思维导图
域名解析过程
流程图
个人是这么理解的,其中可能还有更多的步骤,但是大概如此
详细解释
第一步:检查浏览器缓存中是否缓存过该域名对应的IP地址
用户通过浏览器浏览过某网站之后,浏览器就会自动缓存该网站域名对应的地址,当用户再次访问的时候,浏览器就会从缓存中查找该域名对应的IP地址,因为缓存不仅是有大小限制,而且还有时间限制(域名被缓存的时间通过属性来设置),所以存在域名对应的找不到的情况。当浏览器从缓存中找到了该网站域名对应的地址,那么整个解析过程结束,如果没有找到,将进行下一步骤。对于的缓存时间问题,不宜设置太长的缓存时间,时间太长,如果域名对应的发生变化,那么用户将在一段时间内无法正常访问到网站,如果太短,那么又造成频繁解析域名。
第二步:如果在浏览器缓存中没有找到IP,那么将继续查找本机系统是否缓存过IP
如果第一个步骤没有完成对域名的解析过程,那么浏览器会去系统缓存中查找系统是否缓存过这个域名对应的地址,也可以理解为系统自己也具备域名解析的基本能力。在系统中,可以通过设置文件来将域名手动绑定到某上,文件位置在。对于普通用户,并不推荐自己手动绑定域名和,对于开发者来说,通过绑定域名和,可以轻松切换环境,可以从测试环境切换到开发环境,方便开发和测试。在系统中,黑客常常修改他的电脑的文件,将用户常常访问的域名绑定到他指定的上,从而实现了本地解析,导致这些域名被劫持。在或者系统中,文件在,修改该文件也可以实现同样的目的。
前两步都是在本机上完成的,所以没有在上面示例图上展示出来,从第三步开始,才正在地向远程DNS服务器发起解析域名的请求。
第三步:向本地域名解析服务系统发起域名解析的请求
如果在本机上无法完成域名的解析,那么系统只能请求本地域名解析服务系统进行解析,本地域名系统一般都是本地区的域名服务器,比如你连接的校园网,那么域名解析系统就在你的校园机房里,如果你连接的是电信、移动或者联通的网络,那么本地域名解析服务器就在本地区,由各自的运营商来提供服务。对于本地服务器地址,系统使用命令就可以查看,在和系统下,直接使用命令来查看服务地址。一般都缓存了大部分的域名解析的结果,当然缓存时间也受域名失效时间控制,大部分的解析工作到这里就差不多已经结束了,负责了大部分的解析工作。
第四步:向根域名解析服务器发起域名解析请求
本地域名解析器还没有完成解析的话,那么本地域名解析服务器将向根域名服务器发起解析请求。
第五步:根域名服务器返回gTLD域名解析服务器地址
本地域名解析向根域名服务器发起解析请求,根域名服务器返回的是所查域的通用顶级域()地址,常见的通用顶级域有、、、等。
第六步:向gTLD服务器发起解析请求
本地域名解析服务器向gTLD服务器发起请求。
第七步:gTLD服务器接收请求并返回Name Server服务器
服务器接收本地域名服务器发起的请求,并根据需要解析的域名,找到该域名对应的域名服务器,通常情况下,这个服务器就是你注册的域名服务器,那么你注册的域名的服务商的服务器将承担起域名解析的任务。
第八步:Name Server服务器返回IP地址给本地服务器
服务器查找域名对应的地址,将地址连同值返回给本地域名服务器。
第九步:本地域名服务器缓存解析结果
本地域名服务器缓存解析后的结果,缓存时间由时间来控制。
第十步:返回解析结果给用户
解析结果将直接返回给用户,用户系统将缓存该地址,缓存时间由来控制,至此,解析过程结束。
这里对解析的步骤进行了一个简单的介绍分析,后面将通过命令行的形式来解析一个域名的具体解析过程。
实验演示
查看baidu.com的DNS解析过程
第一步:从本地域名解析服务器获取到个根域名服务器对应的主机名。
第二步:从个根域名服务器中的其中一个(这里是)获取到顶级的服务器(未显示)和名称
第三步:向域的一台服务器请求解析,它返回了域的服务器(未显示)和名称,百度有四台顶级域的服务器
第四步:向百度的顶级域服务器请求,它发现这个有个别名,而不是一台主机,别名是。
一般情况下,解析到别名就停止了,返回了具体的地址,如果想看到具体的地址,可以进一步对别名进行解析,解析结果如下:
DNS相关知识
DNS缓存:DNS 服务器在解析客户机请求时,如果本地没有该DNS 信息,则可以会询问其他DNS 服务器,当其他域名服务器返回查询结果时,该DNS 服务器会将结果记录在本地的缓存中,成为DNS 缓存.当下一次客户机提交相同请求时,DNS 服务器能够直接使用缓存中的DNS 信息进行解析.
DNS报文有两种:查询报文,回答报文,有相同的格式
1)12个字节的首部区域
2)问题区域
3)回答区域
4)权威区域
5)附加区域
web页面解析流程
自己大概是清楚整个流程的,只不过可能是对整个过程的概念不太熟悉,于是,网上找资料,再详细的总结一下
域名解析
这个在第一部分已经说过了,就不介绍了
三次握手建立
字段解释
先理解一下tcp三次握手的时候的关键报文字段
TCP的序号和确认号:32位序号 seq:Sequence number 缩写seq ,TCP通信过程中某一个传输方向上的字节流的每个字节的序号,通过这个来确认发送的数据有序,比如现在序列号为1000,发送了1000,下一个序列号就是2000。32位确认号 ack:Acknowledge number 缩写ack,TCP对上一次seq序号做出的确认号,用来响应TCP报文段,给收到的TCP报文段的序号seq加1。
TCP的标志位每个TCP段都有一个目的,这是借助于TCP标志位选项来确定的,允许发送方或接收方指定哪些标志应该被使用,以便段被另一端正确处理。用的最广泛的标志是 SYN,ACK 和 FIN,用于建立连接,确认成功的段传输,最后终止连接。
SYN:简写为S,同步标志位,用于建立会话连接,同步序列号;
ACK: 简写为.,确认标志位,对已接收的数据包进行确认;
FIN: 简写为F,完成标志位,表示我已经没有数据要发送了,即将关闭连接;
PSH:简写为P,推送标志位,表示该数据包被对方接收后应立即交给上层应用,而不在缓冲区排队;
RST:简写为R,重置标志位,用于连接复位、拒绝错误和非法的数据包;
URG:简写为U,紧急标志位,表示数据包的紧急指针域有效,用来保证连接不被阻断,并督促中间设备尽快处理;
详细流程
第一次握手:客户端将TCP报文标志位SYN置为1,随机产生一个序号值seq=J,保存在TCP首部的序列号(Sequence Number)字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入SYN_SENT状态,等待服务器端确认。
第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将TCP报文标志位SYN和ACK都置为1,ack=J+1,随机产生一个序号值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。
第三次握手:客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
简单流程图
http请求响应
nginx处理流程
POST_READ
读取HTTP头部,读取并解析内容
server-rewrite
在URL与location匹配之前修改请求的URL(重定向),在server块中的请求地址重写
find-config
配置查找阶段,根据请求的URL匹配location表达式;不支持nginx模块注册处理程序,而是由ngx_http_core_module模块来完成当前请求与location配置之间的匹配
rewritelocation
块追踪的请求地址重写阶段,当rewrite指令用于location中则运行;ngx_lua模块中的set_by_lua指令和rewrite_by_lua指令也在这里
post-rewrite
请求地址重写提交阶段,防止递归修改URL造成死循环;由ngx_http_core_module模块实现
preaccess
访问权限检查准备阶段,http模块进入处理阶段,ngx_limit_req(访问控制的频率)和ngx_limit_zone(访问的并发率控制)也会运行
access
访问权限检查执行阶段,ngx_access和nginx_auth_request,ngx_lua的access-by_lua执行在这个阶段,配置指令多是执行访问控制性质的任务,比如检查用户的访问权限,检查用户的IP地址合法性
post-access
访问权限检查提交阶段,如果请求不被允许访问Nginx服务器,该阶段用于返回错误的响应
try-files
配置项try-files处理阶段,如果http访问的静态文件try-files配置项可以使这个请求顺序地访问多个静态文件,直至符合条件
content
内容产生阶段,大部分HTTP模块会执行,所有请求处理阶段中的重要阶段这个阶段的指令通常用来生成HTTP响应的内容
**log
日志模块处理阶段,记录日志
Apache请求处理
Post-Read-Request:
在正常请求处理流程中,这是模块可以插入钩子的第一个阶段。对于那些想很早进入处理请求的模块来说,这个阶段可以被利用。
URI Translation阶: Apache在本阶段的主要工作:将请求的URL映射到本地文件系统。模块可以在这阶段插入钩子,执行自己的映射逻辑。mod_alias就是利用这个阶段工作的。
Header Parsing:
Apache在本阶段的主要工作:检查请求的头部。由于模块可以在请求处理流程的任何一个点上执行检查请求头部的任务,因此这个钩子很少被使用。mod_setenvif就是利用这个阶段工作的。
Access Control :
Apache在本阶段的主要工作:根据配置文件检查是否允许访问请求的资源。Apache的标准逻辑实现了允许和拒绝指令。mod_authz_host就是利用这个阶段工作的。
Authorization :
Apache在本阶段的主要工作:根据配置文件检查是否允许认证过的用户执行请求的操作。模块可以在这阶段插入钩子,实现一个用户权限管理的方法。
MIME Type Checking : Apache在本阶段的主要工作:根据请求资源的MIME类型的相关规则,判定将要使用的内容处理函数。标准模块mod_negotiation和mod_mime实现了这个钩子。
FixUp :
这是一个通用的阶段,允许模块在内容生成器之前,运行任何必要的处理流程。和Post_Read_Request类似,这是一个能够捕获任何信息的钩子,也是最常使用的钩子。
Response :
Apache在本阶段的主要工作:生成返回客户端的内容,负责给客户端发送一个恰当的回复。这个阶段是整个处理流程的核心部分。
Logging :
Apache在本阶段的主要工作:在回复已经发送给客户端之后记录事务。模块可能修改或者替换Apache的标准日志记录。
CleanUp:
Apache在本阶段的主要工作:清理本次请求事务处理完成之后遗留的环境,比如文件、目录的处理或者Socket的关闭等等,这是Apache一次请求处理的最后一个阶段。
http 协议中的字段及含义
请求报文的组成
请求行 + 信息头 + 请求头 + 实体头 + 报文主体
通用首部字段
- Cache-Control字段
通过指定首部字段 Cache-Control 的指令,就能操作缓存的工作机制。 缓存请求指令一览
指令 | Client | Server |
---|---|---|
no-cache | 不接收缓存过的响应 | 不能对资源进行缓存 |
no-store | 不缓存请求或响应的任何内容 | 不缓存请求或响应的任何内容 |
max-age = [秒] | 接收缓存时间比max-age数值更小的资源 | 代表资源保存为缓存的最长时间 |
max-stale = [秒] | 接收已过期的响应 | |
min-fresh = [秒] | 期望在指定时间内的响应仍有效 | |
no-transform | 代理不可更改媒体类型 | |
only-if-cached | 从缓存获取资源 | |
cache-extension | 新指令标记 |
-
Connection字段
具备两个作用:
-
控制不再转发给代理的首部字段
conneciton: upgrade
表示Upgrade首部字段产生作用的Upgrade对象仅限于客户端和邻接服务器之间。
-
-
管理持久连接
HTTP/1.1 版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定
Connection 首部字段的值为 Close。 -
Date字段
首部字段 Date 表明创建 HTTP 报文的日期和时间。
-
Transfer-Encoding字段
首部字段 Transfer-Encoding 规定了传输报文主体时采用的编码方式。
-
Upgrade字段
首部字段 Upgrade 用于检测 HTTP 协议及其他协议是否可使用更高的
版本进行通信,其参数值可以用来指定一个完全不同的通信协议。 -
Via字段
使用首部字段 Via 是为了追踪客户端与服务器之间的请求和响应报文的传输路径。
请求头部
首部字段名 | 说明 |
---|---|
Accept | 用户理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言 |
Authorization | Web认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户的电子邮箱 |
Host | 请求资源所在的服务器 |
If-Match | 比较实体标志(ETag) |
If-None-Match | 比较实体标志(ETag) |
If-Modified-Since | 比较资源更新时间 |
If-Range | 资源未更新时发送实体Byte的范围请求 |
If-Unmodified-Since | 比较资源更新时间(与If-Modified-Since相反) |
Max-Forward | 最大传输逐跳数 |
Proxy-Authorization | 代理服务器要求客⼾端的认证信息 |
Referer | 对请求中URI的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP客户端程序信息 |
响应头部
首部字段 | 说明 |
---|---|
Accept-Ranges | 是否接受字段范围请求 |
Age | 推算资源创建经过时间 |
ETag | 资源匹配信息 |
Location | 令客户端重定向至指定URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
实体头部
Allow | 可支持的HTTP方法 |
---|---|
Content-Encoding | 实体主体适用的编码方式 |
Content-Laguage | 实体主英文名称体的自然语言 |
Content-Length | 实体主体的大小 |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体主体的摘要 |
Content-Type | 实体主体的媒体类型 |
Content-Range | 实体主体的位置范围 |
Expires | 实体主体过期的日期时间 |
Last-Modied | 资源最后修改的日期时间 |
Cookie 服务的首部字段
-
Set-Cookie
NAME=VALUE 赋予 Cookie 的名称和其值(必需项) expires=DATE Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止) path=PATH 将服务器上的文件目录作为Cookie的适用对象(若不指定则默
认为文档所在的文件目录)domain=域名 作为 Cookie 适用对象的域名 (若不指定则默认为创建 Cookie
的服务器的域名)Secure 仅在 HTTPS 安全通信时才会发送 Cooki HttpOnly 加以限制,使 Cookie 不能被 JavaScript 脚本访问
其他首部字段
- X-Frame-Options
首部字段 X-Frame-Options 属于 HTTP 响应首部,用于控制网站内容在其他 Web 网站的 Frame 标签内的显示问题。其主要目的是为了防止点击劫持 (clickjacking)攻击
-
X-XSS-Protection
首部字段 X-XSS-Protection 属于 HTTP 响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关
-
DNT
首部字段 DNT 属于 HTTP 请求首部,其中 DNT 是 Do Not Track 的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法
-
P3P
首部字段 P3P 属于 HTTP 相应首部,通过利用 P3P(The Platform forPrivacy Preferences,在线隐私偏好平台)技术,可以让 Web 网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的
http请求方法
HTTP请求方式分为GET 、POST 、PUT 、HEAD 、DELETE 、OPTIONS 、TRACE和CONNECT 八种。
GET:获取资源
GET 方法用来请求访问已被URI 识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回;如果是像CGI(Common Gateway Interface,通用网关接口)那样的程序,则返回经过执行后的输出结果
POST:传输实体主体
POST 方法用来传输实体的主体。
虽然用GET 方法也可以传输实体的主体,但⼀般不用GET 方法进行传输,而是用POST 方法。虽说POST 的功能与GET 很相似,但POST 的主要目的并不是获取响应的主体内容。
PUT:传输文件
PUT 方法用来传输文件。就像FTP协议的文件上传⼀样,要求请求报文的主题中包含文件内容,然后保存到请求URI的位置。但是,鉴于HTTP/1.1的PUT 方法自身不带验证机制,任何⼈都可以上传文件,存在安全性问题,因此⼀般的Web网站不使用该方法。
HEAD:获取报文首部
HEAD 方法和GET方法⼀样,只是不返回报文主体部分。勇于确认URI 的有效性及资源更新的日期时间等。
DELETE:删除文件
DELETE 方法用来删除文件,是与PUT 相反的方法。DELETE方法按请求URI 删除指定的资源。例如:
OPTIONS:询问支持方法
OPTIONS方法用来查询针对请求URI 指定的资源支持的方法。
TRACE:追踪路径
TRACE方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。
发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器端就将该数字减 1 ,当数值刚好减到 0 时,就停止继续传输,最后接收到请求的服务器端则返回状态码 200 OK 的响应。
但是,TRACE 方法本来就不怎么常用,再加上它容易引发XST(Cross-Site Tracing,跨站追踪) 攻击,通常就更不会用到了。
响应状态码
概述
1xx消息
这一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。由于HTTP/1.0协议中没有定义任何1xx状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送1xx响应。[4] 这些状态码代表的响应都是信息性的,标示客户应该采取的其他行动。
100 Continue
服务器已经接收到请求头,并且客户端应继续发送请求主体(在需要发送身体的请求的情况下:例如,POST请求),或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。要使服务器检查请求的头部,客户端必须在其初始请求中发送Expect: 100-continue作为头部,并在发送正文之前接收100 Continue状态代码。响应代码417期望失败表示请求不应继续。[2]
101 Switching Protocols
服务器已经理解了客户端的请求,并将通过Upgrade消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到在Upgrade消息头中定义的那些协议。[5] 只有在切换新的协议更有好处的时候才应该采取类似措施。例如,切换到新的HTTP版本(如HTTP/2)比旧版本更有优势,或者切换到一个实时且同步的协议(如WebSocket)以传送利用此类特性的资源。
102 Processing
WebDAV请求可能包含许多涉及文件操作的子请求,需要很长时间才能完成请求。该代码表示服务器已经收到并正在处理请求,但无响应可用。[6]这样可以防止客户端超时,并假设请求丢失。
2xx成功
这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。[2]
200 OK
请求已成功,请求所希望的响应头或数据体将随此响应返回。实际的响应将取决于所使用的请求方法。在GET请求中,响应将包含与请求的资源相对应的实体。在POST请求中,响应将包含描述或操作结果的实体。[7]
201 Created
请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其URI已经随Location头信息返回。假如需要的资源无法及时创建的话,应当返回'202 Accepted'。[8]
202 Accepted
服务器已接受请求,但尚未处理。最终该请求可能会也可能不会被执行,并且可能在处理发生时被禁止。[9]
203 Non-Authoritative Information
服务器是一个转换代理服务器(transforming proxy,例如网络加速器),以200 OK状态码为起源,但回应了原始响应的修改版本。[10][11]
204 No Content
服务器成功处理了请求,没有返回任何内容。[12]
205 Reset Content
服务器成功处理了请求,但没有返回任何内容。与204响应不同,此响应要求请求者重置文档视图。[13]
206 Partial Content
服务器已经成功处理了部分GET请求。类似于FlashGet或者迅雷这类的HTTP 下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。[14]
207 Multi-Status
代表之后的消息体将是一个XML消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。[15]
208 Already Reported
DAV绑定的成员已经在(多状态)响应之前的部分被列举,且未被再次包含。
226 IM Used
服务器已经满足了对资源的请求,对实体请求的一个或多个实体操作的结果表示。[16]
3xx重定向
这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location域中指明。[2]
当且仅当后续的请求所使用的方法是GET或者HEAD时,用户浏览器才可以在没有用户介入的情况下自动提交所需要的后续请求。客户端应当自动监测无限循环重定向(例如:A→B→C→……→A或A→A),因为这会导致服务器和客户端大量不必要的资源消耗。按照HTTP/1.0版规范的建议,浏览器不应自动访问超过5次的重定向。[17]
3xx 重定向
被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。[18] 除非这是一个HEAD请求,否则该响应应当包括一个资源特性及地址的列表的实体,以便用户或浏览器从中选择最合适的重定向地址。这个实体的格式由Content-Type定义的格式所决定。浏览器可能根据响应的格式以及浏览器自身能力,自动作出最合适的选择。当然,RFC 2616规范并没有规定这样的自动选择该如何进行。 如果服务器本身已经有了首选的回馈选择,那么在Location中应当指明这个回馈的URI;浏览器可能会将这个Location值作为自动重定向的地址。此外,除非额外指定,否则这个响应也是可缓存的。
301 Moved Permanently
被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。[19]除非额外指定,否则这个响应也是可缓存的。 新的永久性的URI应当在响应的Location域中返回。除非这是一个HEAD请求,否则响应的实体中应当包含指向新的URI的超链接及简短说明。 如果这不是一个GET或者HEAD请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。 注意:对于某些使用HTTP/1.0协议的浏览器,当它们发送的POST请求得到了一个301响应的话,接下来的重定向请求将会变成GET方式。
302 Found
要求客户端执行临时重定向(原始描述短语为“Moved Temporarily”)。[20]由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。 新的临时性的URI应当在响应的Location域中返回。除非这是一个HEAD请求,否则响应的实体中应当包含指向新的URI的超链接及简短说明。 如果这不是一个GET或者HEAD请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。 注意:虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将302响应视作为303响应,并且使用GET方式访问在Location中规定的URI,而无视原先请求的方法。[21]因此状态码303和307被添加了进来,用以明确服务器期待客户端进行何种反应。[22]
303 See Other
对应当前请求的响应可以在另一个URI上被找到,当响应于POST(或PUT / DELETE)接收到响应时,客户端应该假定服务器已经收到数据,并且应该使用单独的GET消息发出重定向。[23]这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源。这个新的URI不是原始资源的替代引用。同时,303响应禁止被缓存。当然,第二个请求(重定向)可能被缓存。 新的URI应当在响应的Location域中返回。除非这是一个HEAD请求,否则响应的实体中应当包含指向新的URI的超链接及简短说明。 注意:许多HTTP/1.1版以前的浏览器不能正确理解303状态。如果需要考虑与这些浏览器之间的互动,302状态码应该可以胜任,因为大多数的浏览器处理302响应时的方式恰恰就是上述规范要求客户端处理303响应时应当做的。
304 Not Modified
表示资源在由请求头中的If-Modified-Since或If-None-Match参数指定的这一版本之后,未曾被修改。在这种情况下,由于客户端仍然具有以前下载的副本,因此不需要重新传输资源。[24]
305 Use Proxy
被请求的资源必须通过指定的代理才能被访问。Location域中将给出指定的代理所在的URI信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能创建305响应。许多HTTP客户端(像是Mozilla[25]和Internet Explorer)都没有正确处理这种状态代码的响应,主要是出于安全考虑。[26] 注意:RFC 2068中没有明确305响应是为了重定向一个单独的请求,而且只能被原始服务器建立。忽视这些限制可能导致严重的安全后果。
306 Switch Proxy
在最新版的规范中,306状态码已经不再被使用。最初是指“后续请求应使用指定的代理”。[27]
307 Temporary Redirect
在这种情况下,请求应该与另一个URI重复,但后续的请求应仍使用原始的URI。 与302相反,当重新发出原始请求时,不允许更改请求方法。 例如,应该使用另一个POST请求来重复POST请求。[28]
308 Permanent Redirect
请求和所有将来的请求应该使用另一个URI重复。 307和308重复302和301的行为,但不允许HTTP方法更改。 例如,将表单提交给永久重定向的资源可能会顺利进行。[29]
4xx客户端错误
这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个HEAD请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。[30]
如果错误发生时客户端正在传送数据,那么使用TCP的服务器实现应当仔细确保在关闭客户端与服务器之间的连接之前,客户端已经收到了包含错误信息的数据包。如果客户端在收到错误信息后继续向服务器发送数据,服务器的TCP栈将向客户端发送一个重置数据包,以清除该客户端所有还未识别的输入缓冲,以免这些数据被服务器上的应用程序读取并干扰后者。
400 Bad Request
由于明显的客户端错误(例如,格式错误的请求语法,太大的大小,无效的请求消息或欺骗性路由请求),服务器不能或不会处理该请求。[31]
401 Unauthorized
参见:HTTP基本认证、HTTP摘要认证 类似于403 Forbidden,401语义即“未认证”,即用户没有必要的凭据。[32]该状态码表示当前请求需要用户验证。该响应必须包含一个适用于被请求资源的WWW-Authenticate信息头用以询问用户信息。客户端可以重复提交一个包含恰当的Authorization头信息的请求。[33]如果当前请求已经包含了Authorization证书,那么401响应代表着服务器验证已经拒绝了那些证书。如果401响应包含了与前一个响应相同的身份验证询问,且浏览器已经至少尝试了一次验证,那么浏览器应当向用户展示响应中包含的实体信息,因为这个实体信息中可能包含了相关诊断信息。 注意:当网站(通常是网站域名)禁止IP地址时,有些网站状态码显示的401,表示该特定地址被拒绝访问网站。
402 Payment Required
该状态码是为了将来可能的需求而预留的。该状态码最初的意图可能被用作某种形式的数字现金或在线支付方案的一部分,但几乎没有哪家服务商使用,而且这个状态码通常不被使用。如果特定开发人员已超过请求的每日限制,Google Developers API会使用此状态码。[34]
403 Forbidden
主条目:HTTP 403 服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个HEAD请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息。
404 Not Found
主条目:HTTP 404 请求失败,请求所希望得到的资源未被在服务器上发现,但允许用户的后续请求。[35]没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。
405 Method Not Allowed
请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow头信息用以表示出当前资源能够接受的请求方法的列表。例如,需要通过POST呈现数据的表单上的GET请求,或只读资源上的PUT请求。 鉴于PUT,DELETE方法会对服务器上的资源进行写操作,因而绝大部分的网页服务器都不支持或者在默认配置下不允许上述请求方法,对于此类请求均会返回405错误。
406 Not Acceptable
参见:内容协商 请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体,该请求不可接受。[36] 除非这是一个HEAD请求,否则该响应就应当返回一个包含可以让用户或者浏览器从中选择最合适的实体特性以及地址栏表的实体。实体的格式由Content-Type头中定义的媒体类型决定。浏览器可以根据格式及自身能力自行作出最佳选择。但是,规范中并没有定义任何作出此类自动选择的标准。
407 Proxy Authentication Required
与401响应类似,只不过客户端必须在代理服务器上进行身份验证。[37]代理服务器必须返回一个Proxy-Authenticate用以进行身份询问。客户端可以返回一个Proxy-Authorization信息头用以验证。
408 Request Timeout
请求超时。根据HTTP规范,客户端没有在服务器预备等待的时间内完成一个请求的发送,客户端可以随时再次提交这一请求而无需进行任何更改。[38]
409 Conflict
表示因为请求存在冲突无法处理该请求,例如多个同步更新之间的编辑冲突。
410 Gone
表示所请求的资源不再可用,将不再可用。当资源被有意地删除并且资源应被清除时,应该使用这个。在收到410状态码后,用户应停止再次请求资源。[39]但大多数服务端不会使用此状态码,而是直接使用404状态码。
411 Length Required
服务器拒绝在没有定义Content-Length头的情况下接受请求。在添加了表明请求消息体长度的有效Content-Length头之后,客户端可以再次提交该请求。[40]
412 Precondition Failed
服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。[41]这个状态码允许客户端在获取资源时在请求的元信息(请求头字段数据)中设置先决条件,以此避免该请求方法被应用到其希望的内容以外的资源上。
413 Request Entity Too Large
前称“Request Entity Too Large”,表示服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。[42]此种情况下,服务器可以关闭连接以免客户端继续发送此请求。 如果这个状况是临时的,服务器应当返回一个Retry-After的响应头,以告知客户端可以在多少时间以后重新尝试。
414 Request-URI Too Long
前称“Request-URI Too Long”,[43]表示请求的URI长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。通常将太多数据的结果编码为GET请求的查询字符串,在这种情况下,应将其转换为POST请求。[44]这比较少见,通常的情况包括: 本应使用POST方法的表单提交变成了GET方法,导致查询字符串过长。 重定向URI“黑洞”,例如每次重定向把旧的URI作为新的URI的一部分,导致在若干次重定向后URI超长。 客户端正在尝试利用某些服务器中存在的安全漏洞攻击服务器。这类服务器使用固定长度的缓冲读取或操作请求的URI,当GET后的参数超过某个数值后,可能会产生缓冲区溢出,导致任意代码被执行[45]。没有此类漏洞的服务器,应当返回414状态码。
415 Unsupported Media Type
对于当前请求的方法和所请求的资源,请求中提交的互联网媒体类型并不是服务器中所支持的格式,因此请求被拒绝。例如,客户端将图像上传格式为svg,但服务器要求图像使用上传格式为jpg。
416 Requested Range Not Satisfiable
前称“Requested Range Not Satisfiable”。[46]客户端已经要求文件的一部分(Byte serving),但服务器不能提供该部分。例如,如果客户端要求文件的一部分超出文件尾端。[47]
417 Expectation Failed
在请求头Expect中指定的预期内容无法被服务器满足,或者这个服务器是一个代理服显的证据证明在当前路由的下一个节点上,Expect的内容无法被满足。[48]
418 I’m a teapot
本操作码是在1998年作为IETF的传统愚人节笑话, 在RFC 2324超文本咖啡壶控制协议’中定义的,并不需要在真实的HTTP服务器中定义。当一个控制茶壶的HTCPCP收到BREW或POST指令要求其煮咖啡时应当回传此错误。[49]这个HTTP状态码在某些网站(包括Google.com)与项目(如Node.js、ASP.NET和Go语言)中用作彩蛋。[50]
420 Enhance Your Caim
Twitter Search与Trends API在客户端被限速的情况下返回。
421 Misdirected Request
该请求针对的是无法产生响应的服务器(例如因为连接重用)。[51]
422 Unprocessable Entity
请求格式正确,但是由于含有语义错误,无法响应。[15]
423 Locked
当前资源被锁定。[15]
424 Failed Dependency
由于之前的某个请求发生的错误,导致当前请求失败,例如PROPPATCH。[15]
425 Unordered Collection
在WebDAV Advanced Collections Protocol中定义,但Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol中并不存在。
426 Upgrade Required
客户端应当切换到TLS/1.0,并在HTTP/1.1 Upgrade header中给出。[15]
428 Precondition Required
原服务器要求该请求满足一定条件。这是为了防止“‘未更新’问题,即客户端读取(GET)一个资源的状态,更改它,并将它写(PUT)回服务器,但这期间第三方已经在服务器上更改了该资源的状态,因此导致了冲突。”[52]
429 Too Many Requests
用户在给定的时间内发送了太多的请求。旨在用于网络限速。[52]
431 Request Header Fields Too Large
服务器不愿处理请求,因为一个或多个头字段过大。[52]
444 No Response
Nginx上HTTP服务器扩展。服务器不向客户端返回任何信息,并关闭连接(有助于阻止恶意软件)。
450 Blocked by Windows Parental Controls
这是一个由Windows家庭控制(Microsoft)HTTP阻止的450状态代码的示例,用于信息和测试。
451 Unavailable For Legal Reasons
主条目:HTTP 451 该访问因法律的要求而被拒绝,由IETF在2015核准后新增加。[53][54][55]
494 Request Header Too Large
在错误代码431提出之前Nginx上使用的扩展HTTP代码。
5xx服务器错误
表示服务器无法完成明显有效的请求。[56]这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个HEAD请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。这些状态码适用于任何响应方法。[57]
500 Internal Server Error
通用错误消息,服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。没有给出具体错误信息。[58]
501 Not Implemented
服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。[59](例如,网络服务API的新功能)
502 Bad Gateway
作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。[60]
503 Service Unavailable
由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是暂时的,并且将在一段时间以后恢复。[61]如果能够预计延迟时间,那么响应中可以包含一个Retry-After头用以标明这个延迟时间。如果没有给出这个Retry-After信息,那么客户端应当以处理500响应的方式处理它。
504 Gateway Timeout
作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。[62] 注意:某些代理服务器在DNS查询超时时会返回400或者500错误。
505 HTTP Version Not Supported
服务器不支持,或者拒绝支持在请求中使用的HTTP版本。[63]这暗示着服务器不能或不愿使用与客户端相同的版本。响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体。
506 Variant Also Negotiates
由《透明内容协商协议》(RFC 2295)扩展,代表服务器存在内部配置错误,[64]被请求的协商变元资源被配置为在透明内容协商中使用自己,因此在一个协商处理中不是一个合适的重点。
507 Insufficient Storage
服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。[15]
508 Loop Detected
服务器在处理请求时陷入死循环。 (可代替 208状态码)
510 Not Extended
获取资源所需要的策略并没有被满足。[65]
511 Network Authentication Required
客户端需要进行身份验证才能获得网络访问权限,旨在限制用户群访问特定网络。(例如连接WiFi热点时的强制网络门户)[52]
扩展思考
整个过程中可能设计涉及到的安全问题
-
明文传输就是在通信的过程中所有的东西都是可见的毫无隐私可言,如果在中间的一些环节,有人恶意地去读取通信信息,那就可能会被窃取一些敏感的信息。而这些就包括最为常见的,用户的账户和密码,或者是银行账号和手机号,只要是在通信中出现了这样的数据就可以被取到。
-
另一种是会被篡改 http 协议的内容,比如,在一个页面中直接插入了一个广告或者小卡片的,而这里小广告通常不是一个静态的图片,而是一个可能带有恶意注入攻击的链接,只要点击了就可能被攻击了或者是再弹出一些乱七八糟的东西。
-
HTTP 协议设计的十分简单,并且不验证通信双方,也就意味着,不论是谁发送的请求,只要合法(后台没有限制访问 ip 和端口号),服务器都会接受,而不确认通信方身份可能会导致以下的问题
网站防护设备常见部署位置
WAF
常见部署于应用之前,最好部署于解密https证书之后。做应用层代理使用。
网战防篡改
部署于应用所在的服务器,通过指定更新方式,锁定进程更新等方式防止网页被篡改
CDN
详细说明如下:
用户向 www.test.com 下的某图片资源(如:1.jpg)发起请求,会先向 Local DNS 发起域名解析请求。
当 Local DNS 解析 www.test.com 时,会发现已经配置了 CNAME www.test.com.cdn.dnsv1.com,解析请求会发送至 Tencent DNS(GSLB),GSLB 为腾讯云自主研发的调度体系,会为请求分配最佳节点 IP。
Local DNS 获取 Tencent DNS 返回的解析 IP。
用户获取解析 IP。
用户向获取的 IP 发起对资源 1.jpg 的访问请求。
若该 IP 对应的节点缓存有 1.jpg,则会将数据直接返回给用户(10),此时请求结束。若该节点未缓存 1.jpg,则节点会向业务源站发起对 1.jpg 的请求(6、7、8),获取资源后,结合用户自定义配置的缓存策略(可参考产品文档中的 缓存过期配置),将资源缓存至节点(9),并返回给用户(10),此时请求结束。
常用部署于dns解析时,就近解析。
https
原理
HTTPS 本质也是基于 HTTP 协议的,不过通过一些安全手段来解决上面 HTTP 存在的问题。它的通用接口部分使用 SSL(Secure Socket Layer) 和 TLS(Transport Layer Security) 协议代替。以前来说,HTTP 协议是应用层协议,直接和下层 TCP 进行通信,而增加了 SSL 协议之后,就变成了 HTTP 先跟 SSL 通信再由 SSL 跟 TCP 通信,也就是说HTTPS是披着 SSL 协议外壳的 HTTP 协议。
SSL 是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 SSP 协议使用。可以说 SSL 是当今世界上应用最为广泛的网络安全技术。
简单来说 HTTPS = HTTP + 加密 + 证书 + 完整性保护
加密
HTTPS 采用混合加密机制,也就是对称加密与非对称加密混用来实现加密机制
数据传输阶段(对称密钥加密)
对称密钥加密又称为共享密钥加密(Common key crypto system),是在加密和解密阶段使用同一个密钥的方式。也就是说,通信双方必须储存同一份密钥,也就是说只要攻击者拿到了密钥,就可以发起攻击。
因此,加密的重中之重就是 如何安全地发送密钥并不泄漏。
证书交换验证阶段(非对称加密)
公开密钥加密(Public-key cryptography)解决了上述的发送密钥问题。它采用一对非对称的密钥,一把公钥一把私钥。加密过程就是,发送加密报文的一方是用对方的公开密钥进行加密,接收方式用自己本地的私钥进行解密,也就是说发送方并不需要附带着发送用来解密的密钥,这种方式就不需要考虑密钥在传输过程中被攻击这获取到。
私钥和公钥是一对多的关系,公钥可以随意转发,只要采用公钥加密的报文,都只能使用对应私钥进行解密。
混合验证机制
HTTPS 采用的是混合加密。
原因是,非对称加密相比对称加密更加复杂,效率更低,在前端业务中一般都是存在大量的 HTTP 请求,所以非对称加密的低效是无法被接受的。此外,非对称加密的场景只在服务端保存私钥,也就是说一对公私钥只能单向传输数据,因此可以用来确认通信安全以及服务端返回证书。确认安全之后,传输数据采用的就是速度更快的对称加密。
证书
上面的过程也存在一个问题,安全的本质是使用密钥进行加密。但是如果密钥本身就有问题,那么安全也就无从谈起,因此这个密钥必须是通信双方认可的。这个工作不能交给客户端做,也不能服务端做,一半交给第三方权威机构 -- 数字证书认证机构(CA,Certificate Authority)。
认证机关的公开密钥必须安全地转交给客户端,使用通信方式是,如何安全转交是一件很困难的事,因此多数浏览器发布版本时,都会是现在内部置入常用认证机关的公钥。
数据完整性
确保数据完整性,也就意味着数据安全没有被第三方篡改,这时候就需要通过 数字签名。
数字签名
数字签名是一段由发送者生成的特殊加密校验码,用于传输过程中确认报文的完整性。数字签名涉及到了两种技术:非对称加密 和 数字摘要。生成数字摘要的算法通过 MD5 和 SHA 这种不可逆算法,将不定长的报文内容提取出定长的数字摘要。
数字签名的整个签名和校验过程分为五步:
发送方用摘要算法对报文提取生成数字摘要
使用私钥对摘要进行加密,加密后的摘要作为数字签名附加在报文上一起发送给接收方
接收方收到报文后,使用相同的摘要算法提取出摘要
在使用公钥对报文的数字签名进行解密
如果解密后的数字签名与提取出的摘要相同,那么说明报文没有被篡改,数据是完整的
多说一句,对于本地存储,无论是服务端的私钥还是客户端的随机数,都不是 HTTPS 通信过程的安全考虑,HTTPS 只保证在网络传输过程的数据安全性,本地的内容安全不被窃取依靠的是防火墙,杀毒软件等等。
握手过程
- 服务端将自己的公钥登录至数字证书认证机构,数字证书认证机构用自己的私钥对服务端公钥署数字签名;
- 客户端发出 HTTPS 请求,请求服务端建立 SSL / TLS 连接;
- 服务端接收到 HTTPS 请求,将申请到的数字证书和服务端公钥一同返回给客户端;
- 客户端在接收到服务端公钥后,数字证书认证机构利用提前植入到浏览器的认证公钥,向数字证书认证机构认证公钥证书上的数字签名,确认服务器公钥的真实性;
- 认证通过之后,客户端随机生成通信使用的密钥,然后使用服务端公钥对密钥进行加密,返回给服务端;
- 服务端收到加密内容后,通过服务端私钥进行非对称解密,得到客户端密钥,至此双方都获得了对称加密的密钥;
- 之后,双方使用密钥进行对称加密通信。
完整流程
证书验证阶段
客户端发起 HTTPS 请求
服务端返回 HTTPS 证书
客户端验证证书是否合法,不合法则提示警告
数据传输阶段
当证书验证合法后,在本地生成随机密码串
通过公钥加密随机密码串,并把加密后的随机密码串传输到服务端
服务端通过私钥对随机密码串进行解密
服务端通过客户端传入的随机密码串构建对称加密算法,对返回的结果内容进行加密后传输