一、什么是HTTP?
Hypertext Transfer Protocol(HTTP)协议(RFC7230)
一种无状态的、应用层、以请求/应答方式运行的协议,它使用可扩展的语义和自描述消息格式,与基于网络的超文本信息系统灵活的互动。
二、HTTP请求行与响应行
请求行格式(ABNF方式描述)
Request-line = method SP request-target SP HTTP-version CRLF
HTTP常见方法(RFC7231)
GET:主要的获取信息方法,大量的性能优化都针对该方法,幂等方法
HEAD:类似GET方法,但服务器不发送BODY,用以获取HEAD元数据,幂等方法
POST:常用于提交HTML FORM表单、新增资源等
PUT:更新资源,带条件时是幂等方法
DELETE:删除资源,幂等方法
CONNECT:建立tunnel隧道
OPTIONS:显示服务器对访问资源支持的方法,幂等方法
TRACE:回显服务器收到的请求,用于定位问题。有安全风险
Request-target
origin-form:后端请求资源的路径,为空时传递/
absolute-form:用于正向代理
authority-form:用于CONNECT方法
asterisk-form:用于OPTIONS方法
HTTP-version 版本号发展历史
HTTP/0.9:只支持GET,已过时
HTTP/1.0:RFC1945,1996,常见使用于代理服务器(例如NGINX默认配置)
HTTP/1.1:RFC2616,1999
HTTP/2.0:2015.5 正式发布
响应行格式(ABNF方式描述)
Status-line = HTTP-version SP status-code SP reason-phrase CRLF
status-code = 3DIGIT
Reason-phrase=*(HTAB/SP/VCHAR/obs-text)
Status-code(响应码)分类
响应码规范:RFC6585(2012.4) RFC7231 (2014.6)
1xx:请求已经收到,需要进一步处理才能完成,HTTP1.0不支持
- 100 Continue:上传大文件前使用
- 由客户端发起请求中携带Expect:100-continue 头部触发
- 101 Switch Protocols:协议升级使用
- 由客户端发起请求中携带Upgrade:头部触发,如升级websocket或者http/2.0
- 102 Processing:WedDAV请求可能包含许多设计文件操作的子请求,需要很长时间才能完成请求。该代码表示服务器已经收到并正在处理请求,但无响应可用。这样可以防止客户端超时,并假设请求丢失。
2xx:成功处理请求
- 200 OK:成功返回响应
- 201 Created:有新资源在服务器端被成功创建
- 202 Accepted:服务器接收并开始处理请求,但请求未处理完成。这样一个模糊的概念是有意如此设计,可以覆盖更多的场景。例如异步‘需要长时间处理的任务。
- 203 Non-Authoritative Information:当代理服务器修改了 origin server 的原始响应包体时(例如更换了HTML中的元素值),代理服务器可以通过修改200为203的方式告知客户端这一事实,方便客户端为这一行为作出相应的处理。203响应可以被缓存。
- 204 No Content:成功执行了请求且不携带响应包体,并暗示客户端无需更新当前的页面视图
- 205 Reset Content:成功执行了请求且不携带响应包体,同时指明客户端需要更新当前页面视图
- 206 Partial Content:使用range协议时返回部分响应内容时的响应码
- 207 Multi-Status:RFC4918 ,在WEBDAV协议中以XML返回多个资源的状态
- 208 Already Reported:RFC5842,为避免相同集合下资源在207响应码下重复上报,使用208可以使用父集合的响应码
3xx:重定向使用Location指向的资源或者缓存中的资源。在RFC2068中规定客户端重定向次数不应超过5次,以防止死循环
- 300 Multiple Choices:资源有多种表述,通过300返回给客户端后由其自行选择访问哪一种表述。由于缺少明确的细节,300很少使用
- 301 Moved Permanently:资源永久性的重定向到另一个URI中
- 302 Found:资源临时的重定向到另一个URI中
- 303 See Other:重定向到其他资源,常用于POST/PUT等方法的响应中
- 304 Not Modified:当客户端拥有可能过期的缓存时,会携带缓存的标识etag、时间等信息询问服务器缓存是否仍可复用,而304是告诉客户端可以复用缓存
- 307 Temporary Redirect:类似302,但明确重定向后请求方法必须与原请求方法相同,不得改变
- 308 Permanent Redirect:类似301,但明确重定向后请求方法必须与原请求方法相同,不得改变
4xx:客户端出现错误
- 400 Bad Request:服务器认为客户端出现了错误,但不能明确判断为以下哪种错误时使用此错误码。例如HTTP请求格式错误
- 401 Unauthorized:用户认证信息缺失或者不正确,导致服务器无法处理请求
- 407 Proxy Authentication Required:对需要经由代理的请求,认证信息未通过代理服务器的验证
- 403 Forbidden:服务器理解请求的含义,但没有权限执行此请求
- 404 Not Found:服务器没有找到对应的资源
- 410 Gone:服务器没有找到对应的资源,且明确的知道该位置永久性找不到该资源
- 405 Method Not Allowed:服务器不支持请求行中的method方法
- 406 Not Acceptable:对客户端指定的资源表述不存在(例如对语言或者编码有要求),服务器返回表述列表供客户端选择
- 408 Request Timeout:服务器接收请求超时
- 409 Conflict:资源冲突,例如上传文件时目标位置已经存在版本更新的资源
- 411 Length Required:如果请求含有包体且未携带Content-Length头部,且不属于chunk类请求时,返回411
- 412 Precondition Failed:复用缓存时传递的If-Unmodified-Since或If-None-Match头部不被满足
- 413 Payload Too Large/Request Entity Too Large:请求的包体超出服务器能处理的最大长度
- 414 URI Too Long:请求的URI超出服务器能接受的最大长度
- 415 Unsupported Media Type:上传的文件类型不被服务器支持
- 416 Range Not Satisfiable:无法提供Range 请求中指定的那段包体
- 417 Expectation Failed:对于Expect请求头部期待的情况无法满足时的响应码
- 421 Misdirected Request:服务器认为这个请求不该发给它,因为他没有能力处理
- 426 Upgrade Required:服务器拒绝基于当前HTTP协议提供服务,通过Upgrade头部告知客户端必须升级协议才能继续处理
- 428 Precondition Required:用户请求中缺失了条件类头部,例如If-Match
- 429 Too Many Requests:客户端发送请求的速率过快
- 431 Request Header Fields Too Large:请求的HEADER头部大小超过限制
- 451 Unavailable For Legal Reasons: RFC7725,由于法律原因资源不可访问
5xx:服务器端出现错误
- 500 Internal Server Error:服务器内部错误,且不属于以下错误类型
- 501 Not Implemented:服务器不支持实现请求所需要的功能
- 502 Bad Gateway:代理服务器无法获取到合法响应
- 503 Service Unavailable:服务器资源尚未准备好处理当前请求
- 504 Gateway Timeout:代理服务器无法及时的从上游获得响应
- 505 HTTP Version Not Supported:请求使用的HTTP协议版本不支持
- 507 Insufficient Storage:服务器没有足够的空间处理请求
- 508 Loop Detected:访问资源是检测到循环
- 511 Network Authentication Required:代理服务器发现客户端需要进行身份验证才能获得网络访问权限
三、HTTP/1.1
1、connection头部
connection:keep-alive 长连接(HTTP/1.1默认使用长连接,keep-alive无意义)
connection:close 短连接
2、host头部
HTTP/1.1规范要求,不传递Host头部则返回400错误响应码
host头部用于http消息在服务器端路由
Host头部与消息的路由
1、建立TCP连接
确定服务器的IP地址
2、接收请求
3、寻找虚拟主机
匹配Host头部与域名
4、寻找URI的处理代码
匹配URI
5、执行处理请求的代码
访问资源
6、生成HTTP响应
各中间件基于PF架构串行修改响应
7、发送HTTP响应
8、记录访问日志
3、代理服务器转发消息时的头部
X-Forwarded-For:用于代理服务器传递IP
X-Real-IP:用于传递用户IP
Max-Forwards:限制Proxy代理服务器的最大转发次数,仅对TRACE/OPTIONS方法有效
Via:指明经过的代理服务器名称及版本
Cache-Control:禁止代理服务器修改响应包体
4、请求与响应上下文头部
User-Agent:指明客户端的类型信息,服务器可以据此对资源的表述做抉择
Referer:浏览器对来自某一页面的请求自动添加的头部
From:主要用于网络爬虫,告诉服务器如何通过邮件联系到爬虫的负责人
Server:指明服务器上所用软件的信息,用于帮助客户端定位问题或统计数据
Allow:告诉客户端,服务器上该URI对应的资源允许哪些方法的执行
Accept-Ranges:告诉客户端服务器上该资源是否允许range请求(允许服务器基于客户端的请求只发送响应包体的一部分给到客户端,而客户端自动将多个片段的包体组合成完整的体积更大的包体)
5、内容协商与资源表述
Accept-Encoding:内容编码,主要指压缩算法协商
Accept-Language:语言协商
Content-type:资源表述,媒体类型、编码
Content-encoding:资源表述,内容编码
Content-Language:资源表述,语言
6、HTTP包体传输头部
Content-Length:使用Content-Length头部明确指出包体长度
Transfer-Encoding:指明使用Chunk 传输方式,含Transfer-Encoding 头部后Content-Length头部应被忽略
TE头部:客户端在请求在声明是否接受Trailer头部
Trailer头部:服务器告知接下来chunk包体会传输哪些Trailer头部
以下头部不允许出现在Trailer 的值中:
用于信息分帧的首部(例如Transfer-Encoding 和Content-Length)
用于路由用途的首部(例如Host)
请求修饰首部(例如控制类和条件类的,如Cache-Control, Max-Forwards, 或者TE)
身份验证首部(例如Authorization或者Set-Cookie)
Content-Encoding, Content-Type, Content-Range, 以及Trailer 自身
7、Content-Disposition 头部(RFC6266)
disposition-type =" inline"|" attachment"| disp-ext-type
inline: 指定包体是以inline 内联的方式,作为页面的一部分展示
attachment: 指定浏览器将包体以附件的方式下载
在multipart/form-data类型应答中,可以用于子消息体部分
8、Cookie与Set-Cookie头部
Cookie-header:Cookie头部中可以存放多个name/value 名值对
Set-Cookie:Set-Cookie头部一次只能传递1个name/value名值对,响应中可以包含多个头部
9、跨域请求资源请求头部
Access-Control-Request-Method:在preflight预检请求(OPTIONS)中,告知服务器接下来的请求会使用哪些方法
Access-Control-Request-Headers:在preflight预检请求(OPTIONS)中,告知服务器接下来的请求会传递哪些头部
10、跨域请求资源响应头部
Access-Control-Allow-Methods:在preflight预检请求的响应中,告知客户端后续请求允许使用的方法
Access-Control-Allow-Headers:在preflight预检请求的响应中,告知客户端后续请求允许携带的头部
Access-Control-Max-Age:在preflight预检请求的响应中,告知客户端该响应的信息可以缓存多久
Access-Control-Expose-Headers:告知浏览器哪些响应头部可以供客户端使用,默认情况下只有Cache-Control.、Content-Language、Content-Type、Expires、 Last-Modified、Pragma 可供使用
Access-Control-Allow-Origin:告知浏览器允许哪些域访问当前资源, *表示允许所有域。 为避免缓存错乱,响应中需要携带Vary: Origin
Access-Control-Allow-Credentials:告知浏览器是否可以将Credentials暴露给客户端使用,Credentials包含cookie、 authorization类头部、TLS证书等。
11、验证器响应头部
Etag:给出当前资源表述的标签
Last-Modified:表示对应资源表述的上次修改时间
12、验证请求与响应头部
验证请求
若缓存响应中含有Last-Modified头部
If-Unmodified-Since
If-Modified-Since
If-Range
若缓存响应中含有Etag头部
If-None-Match
If-Match
If-Range
13、缓存相关头部
Age:Age表示自源服务器发出响应(或者验证过期缓存) ,到使用缓存的响应发出时经过的秒数
Cache-Control:缓存控制头部
Cache-Control头部在请求中的值
Max-age:告诉服务器,客户端不会接受Age超出max-age秒的缓存
Max-stale:告诉服务器,即使缓存不再新鲜,但陈旧秒数没有超出max-stale时,客户端扔打算使用。若max-stale后没有值,则表示无论过期多久客户端都可使用
Min-fresh:告诉服务器,Age至少经过min-fresh秒后缓存才可使用
No-cache:告诉服务器,不能直接使用已有缓存作为响应返回,除非带着缓存条件到上游服务端得到304验证返回码才可使用现有缓存
No-store:告诉各代理服务器不要对该请求的响应缓存(实际有不少不遵守该规定的代理服务器)
No-transform:告诉代理服务器不要修改消息包体的内容
Only-if-cached:告诉服务器仅能返回缓存的响应,否则若没有缓存则返回504错误码
Cache-Control头部在响应中的值
Must-revalidate:告诉客户端一旦缓存过期,必须向服务器验证后才可使用
Proxy-revalidate:与Must-revalidate类似,但它仅对代理服务器的共享缓存有效
No-cache:告诉客户端不能直接使用缓存的响应,使用前必须在源服务器验证得到304返回码。如果no-cache后指定头部,则若客户端的后续请求及响应中不含有这些头则可直接使用缓存
Max-age:告诉客户端缓存Age超出max-age秒后则缓存过期
S-maxage:与max-age相似,但仅对共享缓存,且优先级高于max-age和Expires
public:表示无论私有缓存或者共享缓存,皆可将该响应缓存
private:表示该响应不能被代理服务器作为共享缓存使用。若private后指定头部,则在告诉代理服务器不能缓存指定的头部,但可缓存其他部分
No-store:告诉所有下游节点不能对响应进行缓存
No-transform:告诉代理服务器不能修改消息包体的内容
14、重定向头部
Location :当浏览器接收到重定向响应码时,需要读取响应头部Location头部的值,获取到新的URI再跳转访问该页面
参考文章:http://taohui.pub/