仍然记得研究生毕业时,也就是15年底(12月初)去一家公司面试,第三轮时那面试官扔我一本《HTTP权威指南 》,说”给你1小时,然后你再跟我讲讲什么是HTTP”。
时光飞逝,18年5月,工作正好两年,换工作。我一个两年工作经验的后端Java开发再一次被问到:讲述一下HTTP。
以上即是菜逼我写这篇文章的缘由。记录一下自己对HTTP的理解。
HTTP涉及到的东西太多,想讲清楚不容易。
什么是HTTP
超文本传输协议,用来传输诸如 HTML 的超媒体文档等数据的,是基于 TCP/IP 的应用层协议。被设计用于Web浏览器和Web服务器之间的通信,是一种 client-server 协议,通过交换各自的消息(与数据流正好相反)来进行交互,客户端如浏览器发出的消息叫做 requests,服务端回应的消息就叫做 responses。HTTP是无状态协议,意味着服务器不会在两个请求之间保留任何数据(状态)。
HTTP 使用面向连接的TCP作为传输层协议。HTTP 本身无连接。
HTTP请求由三部分组成:请求行Request line、请求头Request header、请求正文body;header和body之间有个空行。
请求行以一个方法符号开头,以空格分开,后面跟着请求 URI 和协议的版本,格式如下:
Method Request-URI HTTP-Version CRLF
Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;
CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。
HTTP响应也是由三个部分组成:响应行Response line、响应报头Response header、响应正文body;header和body之间也有个空行。
Response 消息中的第一行叫做状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
Reason-Phrase表示状态代码的文本描述。
其主要特点:
- 支持客户/服务器模式。
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定客户与服务器联系的类型不同。由于简单,使得HTTP服务器的程序规模小,因而通信速度很快。
- 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP & TCP/UDP
TCP、HTTP、UDP,都是通信协议。TCP/IP是个协议组,可分为四个层次:网络接口层、网络层、传输层和应用层。
网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。
传输层中有TCP协议与UDP协议。
应用层有FTP、HTTP、TELNET、SMTP、DNS等协议。
HTTP本身就是一个协议,是从Web服务器传输超文本到本地浏览器的传送协议。
TCP 被称为“面向连接”的传输层协议。TCP 比 UDP 更可靠。HTTP是基于 TCP/IP 的,有很多常见的应用层协议是以 TCP 为基础的,如FTP、SMTP、POP、IMAP等。通常而言,HTTP基于TCP / IP层,但可以在任何可靠的传输层上使用;也就是说,一个不会静默丢失消息的协议,如UDP。
Socket:
这是为了实现以上的通信过程而建立成来的通信管道,其真实的代表是客户端和服务器端的一个通信进程,双方进程通过socket进行通信,而通信的规则采用指定的协议。socket只是一种连接模式,不是协议,TCP、UDP,简单的说(虽然不准确)是两个最基本的协议,很多其它协议都是基于这两个协议如,http就是基于TCP的,用socket可以创建TCP连接,也可以创建UDP连接,用socket可以创建任何协议的连接,因为其它协议都是基于此的。
短连接和长连接
HTTP 对 TCP 连接的使用,分为两种方式:短连接和长连接(持久连接,Keep-Alive或Persistent Connection)
浏览器发起一个TCP连接请求,获得HTML源码,解析到HTML里面有很多外部超媒体资源(图片,CSS,JS),如果是短连接模式,则一个HTML请求结束之后,就关闭连接;对于外部资源再开启一个连接请求,获得相应,如此多次连接多次相应。而长连接模式下,解析出来需要的所有外部资源,使用一个TCP连接(获得资源需要一定时间,故而需要保持连接 keep-alive),一次性把所有需要加载的资源获取到。
在 HTTP 1.0 版本,默认使用的是短连接(Web 诞生初期,网页相对简单,“短连接”的问题不大)。
1995年底开始制定 HTTP 1.1 草案时,网页已经开始变得复杂(网页内的图片、脚本越来越多了)。建立 TCP 连接是有“时间成本”和“CPU 成本。所以,在 HTTP 1.1 中,默认采用的是“Keep-Alive”的方式。
面试问题:TCP和HTTP的关系?TCP和UDP的区别?为什么HTTP不是基于UDP?HTTP基于TCP的使用方式(表述待完善)?
URL
URL一般的组成成分是<协议>://<主机>:<端口号>/<路径>
,更具体的:
schema://host[:port#]/path/.../[?query-string][#anchor]
scheme:协议;host:HTTP服务器的IP地址或者域名;port:HTTP服务器的默认端口是80(可省略),使用别的端口,必须指明;path:访问资源的路径;query-string:发送给http服务器的数据;anchor:锚。
- 协议:
http——超文本传输协议资源
https——用安全套接字层传送的超文本传输协议
ftp——文件传输协议
mailto——电子邮件地址
ldap——轻型目录访问协议搜索
file——当地电脑或网上分享的文件
news——Usenet新闻组
gopher——Gopher协议
telnet——Telnet协议 - 主机:在因特网上的域名
- 端口:有时可省略
- 路径
绝对URL(absolute URL)显示文件的完整路径,这意味着绝对URL本身所在的位置与被引用的实际文件的位置无关。
相对URL(relative URL)以包含URL本身的文件夹的位置为参考点,描述目标文件夹的位置。
如果路径省略URL就指到因特网上的某个主页。
HTTP方法
- OPTIONS:这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用
*
来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。 - HEAD:与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。使用这个方法可以在不必传输全部内容的情况下,就可以获取其中
关于该资源的信息
(元信息或称元数据)。 - GET:向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。参见安全方法
- POST:向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。非幂等
- PUT:向指定资源位置上传其最新内容。幂等
- DELETE:请求服务器删除Request-URI所标识的资源。
- TRACE:回显服务器收到的请求,主要用于测试或诊断。
- CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。
- PATCH
用于更新部分资源,比如说,仅仅只需要更新资源的一个字段field,此时使用PUT方法传输整个资源显得笨重,浪费带宽。既不是安全也不是幂等的。
An API implementing PATCH must patch atomically. It MUST not be possible that resources are half-patched when requested by a GET。
虽然HTTP的请求方式有很多种(包括扩展的),在实际应用中常用的也就是get和post,其他请求方式也都可以通过这两种方式间接实现。
与CURD对应关系:
C(POST), U(PUT), R(GET), D(DELETE);
GET和POST区别
- 地址栏
GET提交的数据会在地址栏中显示出来,而POST提交地址栏不会改变。因此,GET请求会出现在浏览器的浏览历史记录中,POST不会。GET请求可以保存到书签,POST不能。- GET提交,请求的数据会附在URL之后以?分割URL和传输数据,多个参数用&连接。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
- POST提交:把提交的数据放置在是HTTP包的包体requestBody中。
- 传输数据的大小
HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。 而在实际开发中存在的限制主要有:- GET:特定浏览器和服务器对URL长度有限制,例如IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。
因此对于GET提交时,传输数据就会受到URL长度的限制。 - POST:由于不是通过URL传值,理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。
- GET:特定浏览器和服务器对URL长度有限制,例如IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。
- 安全性
POST的安全性要比GET的安全性高。比如通过GET提交数据,用户名和密码将明文出现在URL上。 - 传值方式
GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值,也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值; - 缓存
GET可被缓存,POST不能。 - 幂等性
GET是幂等的,无副作用;POST不是幂等的,有副作用。 - TCP数据包
GET产生一个TCP数据包;POST产生两个TCP数据包。
GET请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200(返回数据)。
注:并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
参考
POST & PUT & PATCH
PUT:
- 一般用于更改已有数据,如果一条数据还不存在,应该返回404,否则200;
- PUT 的 URL 必须指向唯一资源,PUT 无论调用几次一定是把这个唯一的资源更新成请求提供的内容,即完全替换,满足幂等;
POST:
- 一般用来创建新数据,如果一个数据已经存在,则应该返回 409 ,否则 200(又一说:创建成功,应该返回201 );
- POST 的 URL 可以指向资源的集合,非幂等,每次 POST 都会增加一个 record
PATCH:
- 非幂等,每次 PATCH 都只会对部分数据进行更新,并且可能出现++的情况。
http 409 Conflict:表示请求与服务器端目标资源的当前状态相冲突。
消息报头
HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成。每一个报头域都是由名字+“:”+空格+值 组成,消息报头域的名字是大小写无关的。
HTTP一共有四种类型的首部字段:
通用首部字段:请求报文和响应报文两方都会使用的首部。
请求首部字段:从客户端向服务器发送请求报文时使用的首部。
响应首部字段:从服务器向客户端返回响应报文时使用的首部。
实体首部字段:针对请求报文和响应报文的实体部分使用的首部。
通用首部字段
在普通报头中,有少数报头域用于所有的请求和响应消息,但并不用于被传输的实体,只用于传输的消息。
首部字段名 | 说明 | 示例 |
---|---|---|
Cache-Control | 控制缓存的行为 | Cache-Control:Public可以被任何缓存所缓存;Cache-Control:Private内容只缓存到私有缓存中;Cache-Control:no-cache所有内容都不会被缓存 |
Connection | 逐跳首部、连接的管理 | Connection:keep-alive当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接; Connection:close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request,需要重新建立TCP连接。 |
Date | 创建报文的日期时间 | |
Pragma | 防止页面被缓存,在HTTP/1.1版本中,和Cache-Control:no-cache作用一模一样,只有一个用法,例如:Pragma:no-cache | |
Trailer | 报文末端的首部一览 | |
Transfer-Encoding | 指定报文主体的传输编码方式 | |
Upgrade | 升级为其他协议 | |
Via | 代理服务器的相关信息 | |
Warning | 错误通知 |
请求报头
请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。
首部字段名 | 说明 | 示例 |
---|---|---|
Accept | 用于指定用户代理(客户端)可处理的媒体类型,如果服务器无法返回text/html类型的数据,服务器应该返回一个406错误(non acceptable)。Accept:*/* 代表浏览器可以处理所有类型。 |
Accept:text/html, image/gif |
Accept-Charset | 用于指定客户端接受的字符集,如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。 | Accept-Charset:iso-8859-1,gb2312. |
Accept-Encoding | 接受的内容编码,通常指定压缩方法,是否支持压缩,支持什么压缩方法;如果请求消息中没有设置这个域服务器假定客户端对各种内容编码都可以接受。 | |
Accept-Language | 接受的语言(自然语言),如果请求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。 | |
Authorization Web | 认证信息 | |
Expect | 期待服务器的特定行为 | |
From | 用户的电子邮箱地址 | |
Host | 请求资源所在服务器 | |
if-Match | 比较实体标记(ETag) | |
if-Modified-Since | 比较资源的更新时间 | |
if-None-Match | 比较实体标记(与if-Match相反) | |
if-Range | 资源未更新时发送实体Byte的范围请求 | |
if-Unmodified-Since | 比较资源的更新时间(与if-Modified-Since相反) | |
Max-Forwards | 最大传输逐跳数 | |
Proxy-Authorization | 代理服务器要求客户端的认证信息 | |
Range | 实体的字节范围请求 | |
Referer | 提供Request的上下文信息的服务器,告诉服务器是从哪个链接过来的。 | |
TE | 传输编码的优先级 | |
User-Agent | 告诉HTTP服务器,客户端使用的操作系统和浏览器的名称和版本。 |
响应首部字段
首部字段名 | 说明 |
---|---|
Accept-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过时间 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定的URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Reter-After | 对再次发起请求的时机要求 |
Server | 指明HTTP服务器的软件信息。 |
Vary | 代理服务器缓存的管理信息 |
www-Authenticate | 服务器对客户端的认证信息 |
实体首部字段
首部字段名 | 说明 |
---|---|
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体的适用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体的大小,即发送给HTTP服务器数据的长度,单位:字节 |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体主体的报文摘要 |
Content-Range | 实体主体的位置范围 |
Content-Type | 实体主体的媒体类型,WEB服务器告诉浏览器自己响应的对象的类型和字符集。 |
Expires | 实体主体过期的日期时间,浏览器会在指定过期时间内使用本地缓存 |
Last-Modified | 资源的最后修改日期时间 |
Date | 生成消息的具体时间和日期 |
响应状态码
1xx(临时响应)
表示临时响应并需要请求者继续执行操作的状态代码,这些状态代码表示临时的响应。客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应。
100 (继续) 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。
101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。
2xx (成功)
201 (已创建) 请求成功并且服务器创建了新的资源。
202 (已接受) 服务器已接受请求,但尚未处理。
203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206 (部分内容) 服务器成功处理了部分 GET 请求。
3xx (重定向)
客户端浏览器必须采取更多操作来实现请求。例如,浏览器可能不得不请求服务器上的不同的页面,或通过代理服务器重复该请求。表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
4xx(客户端错误)
这些状态代码表示请求可能出错,妨碍了服务器的处理。
400 (错误请求Bad Request) 客户端请求有语法错误,不能被服务器所理解。
401 (Unauthorized,未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
402 要求付费。
403 (Forbidden,禁止) 服务器拒绝请求。
404 (未找到) 服务器找不到请求的网页。
405 (方法禁用) 禁用请求中指定的方法。
406 (不接受) 无法使用请求的内容特性响应请求的网页。
407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408 (请求超时) 服务器等候请求时发生超时。
409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410 (过期的/已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件
413 Request Entity Too Large(请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力
414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417 (未满足期望值) 服务器未满足”期望”请求标头字段的要求。
另外,还有更详细的错误码,开发不常见:
401 – 访问被拒绝。IIS 定义许多不同的 401 错误,它们指明更为具体的错误原因。这些具体的错误代码在浏览器中显示,但不在 IIS 日志中显示:
401.1 – 未授权:登录失败
401.2 – 未授权:服务器配置问题导致登录失败
401.3 – 由于 ACL 对资源的限制而未获得授权、ACL 禁止访问资源。
401.4 – 未授权:授权被筛选器拒绝。
401.5 – 未授权:ISAPI/CGI 应用程序授权失败。
401.7 – 访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。
403 – 禁止访问:IIS 定义许多不同的 403 错误,它们指明更为具体的错误原因:
403.1 – 执行访问被禁止。
403.2 – 读访问被禁止。
403.3 – 写访问被禁止。
403.4 – 要求 SSL。
403.5 – 要求 SSL 128。
403.6 – IP 地址被拒绝。
403.7 – 要求客户端证书。
403.8 – 站点访问被拒绝。
403.9 – 用户数过多。
403.10 – 配置无效。
403.11 – 密码更改。
403.12 – 拒绝访问映射表。
403.13 – 客户端证书被吊销。
403.14 – 拒绝目录列表。
403.15 – 超出客户端访问许可/客户访问许可过多。
403.16 – 客户端证书不受信任或无效。
403.17 – 客户端证书已过期或尚未生效。
403.18 – 在当前的应用程序池中不能执行所请求的 URL。这个错误代码为 IIS 6.0 所专用。
403.19 – 不能为这个应用程序池中的客户端执行 CGI。这个错误代码为 IIS 6.0 所专用。
403.20 – Passport 登录失败。这个错误代码为 IIS 6.0 所专用。
404 – 未找到。 404.0 -(无) – 没有找到文件或目录。
404.1 – 无法在所请求的端口上访问 Web 站点。
404.2 – Web 服务扩展锁定策略阻止本请求。
404.3 – MIME 映射策略阻止本请求。
405 – 用来访问本页面的 HTTP 谓词不被允许(方法不被允许)
406 – 客户端浏览器不接受所请求页面的 MIME 类型。
407 – 要求进行代理身份验证。
410 – 永远不可用
412 – 前提、先决条件失败。
413 – 请求实体太大。
414 – 请求 URI 太长。
415 – 不支持的媒体类型。
416 – 所请求的范围无法满足。
417 – 执行失败。
423 – 锁定的错误。
5xx(服务器错误)
这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
500 (Internal Server Error,服务器内部错误) 服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
RFC 6585 已经发布,该文档描述了 4 个新的 HTTP 状态码。
HTTP 协议还在变化?是的,HTTP 协议一直在演变,新的状态码对于开发 REST 服务或者说是基于 HTTP 的服务非常有用,下面我们为你详细介绍这四个新的状态码以及是否应该使用。
500-11 服务器关闭
500.12 – 应用程序正忙于在 Web 服务器上重新启动。
500.13 – Web 服务器太忙。
500-14 – 应用程序无效
500.15 – 不允许直接请求 Global.asa。
500.16 – UNC 授权凭据不正确。这个错误代码为 IIS 6.0 所专用。
500.18 – URL 授权存储不能打开。这个错误代码为 IIS 6.0 所专用。
500.100 – 内部 ASP 错误。
501 – 页眉值指定未实现的配置。
502 – Web 服务器用作网关或代理服务器时收到了无效响应。
502.1 – CGI 应用程序超时。
502.2 – CGI 应用程序出错。application.
503 – 服务不可用。这个错误代码为 IIS 6.0 所专用。
428 Precondition Required (要求先决条件)
先决条件是客户端发送 HTTP 请求时,如果想要请求能成功必须满足一些预设的条件。
一个好的例子就是 If-None-Match 头,经常在 GET 请求中使用,如果指定了 If-None-Match ,那么客户端只在响应中的 ETag 改变后才会重新接收回应。
先决条件的另外一个例子就是 If-Match 头,这个一般用在 PUT 请求上用于指示只更新没被改变的资源,这在多个客户端使用 HTTP 服务时用来防止彼此间不会覆盖相同内容。
当服务器端使用 428 Precondition Required 状态码时,表示客户端必须发送上述的请求头才能执行请求,这个方法为服务器提供一种有效的方法来阻止 ‘lost update’ 问题。
429 Too Many Requests (太多请求)
当你需要限制客户端请求某个服务数量时,也就是请求速度限制。
例如 ‘509 Bandwidth Limit Exceeded’. Twitter 使用 420 (这不是HTTP定义的状态码)
如果你希望限制客户端对服务的请求数,可使用 429 状态码,同时包含一个 Retry-After 响应头用于告诉客户端多长时间后可以再次请求服务。
431 Request Header Fields Too Large (请求头字段太大)
某些情况下,客户端发送 HTTP 请求头会变得很大,那么服务器可发送 431 Request Header Fields Too Large 来指明该问题。
HTTP 502 – 网关错误
用户试图通过 HTTP 或文件传输协议 (FTP) 访问一台正在运行 Internet 信息服务 (IIS) 的服务器上的内容时,IIS 返回一个表示该请求的状态的数字代码。该状态代码记录在 IIS 日志中,同时也可能在 Web 浏览器或 FTP 客户端显示。状态代码可以指明具体请求是否已成功,还可以揭示请求失败的确切原因。
511 Network Authentication Required (要求网络认证)
如果你在开发一个 HTTP 服务器,你不一定需要处理该状态码,但如果你在编写 HTTP 客户端,那这个状态码就非常重要。
如果你频繁使用笔记本和智能手机,你可能会注意到大量的公用 WIFI 服务要求你必须接受一些协议或者必须登录后才能使用。
这是通过拦截HTTP流量,当用户试图访问网络返回一个重定向和登录,这很讨厌,但是实际情况就是这样的。
使用这些“拦截”客户端,会有一些讨厌的副作用。在 RFC 中有提到这两个的例子:
如果你在登录WIFI前访问某个网站,网络设备将会拦截首个请求,这些设备往往也有自己的网站图标 ‘favicon.ico’。登录后您会发现,有一段时间内你访问的网站图标一直是WIFI登录网站的图标。
如果客户端使用HTTP请求来查找文档(可能是JSON),网络将会响应一个登录页,这样你的客户端就会解析错误并导致客户端运行异常,在现实中这种问题非常常见。
因此 511 状态码的提出就是为了解决这个问题。
如果你正在编写 HTTP 的客户端,你最好还是检查 511 状态码以确认是否需要认证后才能访问。
面试题扩展:Nginx中的499状态码?
301 & 302
定义如下:
301 Moved Permanently 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
302 Found 请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行指定的情况下,这个响应才是可缓存的。
同异
共同点:用户都可以看到url替换为一个新的,然后发出请求。
不同点
- 301:适合永久重定向,如访问 http://www.baidu.com 会跳转到 https://www.baidu.com,返回301和location表示新地址,浏览器就会拿着这个新的地址去访问。常用场景是使用域名跳转。301请求是可以缓存的, 即通过看status code,可以发现后面写着from cache。或者你把你的网页的名称从php修改为html,这个过程中,也会发生永久重定向。搜索引擎在抓取新的内容的同时,也将旧的网址替换为重定向之后的网址。
- 302:重定向是暂时的,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的。用来做临时跳转。未登陆的用户访问用户中心重定向到登录页面、访问404页面会重新定向到首页。
niginx 301/302配置
// rewrite + permenent == 301
if ($host != 'awesome.me') {
rewrite ^/(.*)$ http://www.awesome.me/$1 permanent;
}
// rewrite + redirect == 302
if ($host != 'awesome.me') {
rewrite ^/(.*)$ http://www.awesome.me/$1 redirect;
}
HTTP响应码301和302的区别
https://www.jianshu.com/p/995a3000f7d6
状态码301和302的区别
版本号
HTTP/1.0,HTTP/1.1 以及 HTTP 2.0,区别是什么?
请求一个万维网文档需要的时间是2RTT+文档传输时间。因为要和服务器建立TCP连接需要3次握手,在第三次握手的时候捎带发送请求相关的数据,然后HTTP服务器响应报文总共是四次交互,也就是2RTT时间。再加上一些其他的开销,万维网服务器要服务大量的客户,所以每次浏览都需要建立连接,HTTP/1.0中这种非持续连接(短链接)服务器负担很重。HTTP/1.1使用持续连接(长链接),服务器在发送响应后仍然保持这条连接。
持续链接还分为流水线方式和非流水线方式。后者规定客户发送浏览请求得到响应后才能发送下一个。流水线方式客户不用等到响应就可以发送下一个请求,服务器收到请求后就可以连续响应,不用等待,节省时间。
HTTP 1.1的持续连接,需要增加新的请求头来帮助实现。
例如,Connection请求头的值为Keep-Alive时,客户端通知服务器返回本次请求结果后保持连接;Connection请求头的值为close时,客户端通知服务器返回本次请求结果后关闭连接。
HTTP 1.1还提供与身份认证、状态管理和Cache缓存等机制相关的请求头和响应头。
包括现在HTTP 2.0.
HTTP 与 RESTFul
HTTP 2.0
HTTP缓存
HTTP鉴权控制
其他
在nginx中有个配置文件mime.types,主要是标示Content-Type的文件格式。
application/x-www-form-urlencoded是常用的表单发包方式,普通的表单提交,或者js发包,默认都是通过这种方式。
multipart/form-data用在发送文件的POST包,boundary用于分割数据。当文件太长,HTTP无法在一个包之内发送完毕,就需要分割数据,分割成一个一个chunk发送给服务端,–用于区分数据快。
HTTP通信中并不存在所谓的json,而是将string转成json,即application/json可以理解为text/plain,普通字符串。
HTTP指纹识别技术
HTTP指纹识别的原理大致上也是相同的:记录不同服务器对Http协议执行中的微小差别进行识别。Http指纹识别比TCP/IP堆栈指纹识别复杂许多,理由是定制Http服务器的配置文件、增加插件或组件使得更改Http的响应信息变的很容易,这样使得识别变的困难;然而定制TCP/IP堆栈的行为需要对核心层进行修改,所以就容易识别。
要让服务器返回不同的Banner信息的设置是很简单的,象Apache这样的开放源代码的Http服务器,用户可以在源代码里修改Banner信息,然后重起Http服务就生效;对于没有公开源代码的Http服务器比如微软的IIS或者是Netscape,可以在存放Banner信息的Dll文件中修改,当然这样的修改的效果还是不错的。另外一种模糊Banner信息的方法是使用插件。
常用测试请求:
1:HEAD/Http/1.0发送基本的Http请求
2:DELETE/Http/1.0发送那些不被允许的请求,比如Delete请求
3:GET/Http/3.0发送一个非法版本的Http协议请求
4:GET/JUNK/1.0发送一个不正确规格的Http协议请求
Http指纹识别工具Httprint,通过运用统计学原理,组合模糊的逻辑学技术,能很有效的确定Http服务器的类型。它可以被用来收集和分析不同Http服务器产生的签名。
HTTP协议Content Length限制漏洞导致拒绝服务攻击
使用POST方法时,可以设置Content Length来定义需要传送的数据长度,例如ContentLenth:999999999,在传送完成前,内存不会释放,攻击者可以利用这个缺陷,连续向WEB服务器发送垃圾数据直至WEB服务器内存耗尽。这种攻击方法基本不会留下痕迹。
参考
- http://www.cnpaf.net/Class/HTTP/0532918532667330.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/142365.html