简介
HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等
HTTP是建立在TCP协议之上的一种应用层网络协议,由请求和响应构成,虽然HTTP通常依赖tcp作为传输层协议,但是事实上,HTTP可以在任何其他互联网协议上,或者其他网络上实现,只要其下层协议提供可靠的传输,任何能够提供这种保证的协议都可以被其使用
HTTP默认的端口号为80,HTTPS的端口号为443。
目的
HTTP是浏览器和Web Server之间通信的协议,目的是处理客户端和服务端之间的通信
名词解释
- URI Uniform Resource Identifier,统一资源标识符
- URL Uniform Resource Locator,统一资源定位符
- URN(Uniform Resource Name,统一资源名)
URI是互联网统一资源标识符,URL和URN是它的实现的一种方式,URL是通过资源位置路径来标记资源,URN是通过名字(命名空间字符串)来标记,URL和URN都是URI的子集
协议特点
-
方向单一性
HTTP协议永远都是客户端发起请求,服务器回送响应。无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端,即"推送服务" -
无状态协议
协议的状态是指下一次传输可以“记住”这次传输信息的能力,http是不会为了下一次连接而维护这次连接所传输的信息,这是为了更快地处理大量事务,确保协议的可伸缩性,而特意设计的如此简单 (虽然HTTP本身是无状态协议,但可以通过COOKIE技术来保存状态信息) -
持久链接(Connection: keep-alive)
从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,只要任意一端没有明确提出断开,则保持TCP连接状态。 简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache,Nginx)中设定这个时间。 -
管线化
持久链接使得多数请求以管线化方式发送成为可能,使得不必等待收到上个请求的响应结果再发送下一个请求,即可以做到同时并行发送多个请求,而管线化技术比持久链接还要快 参考HTTP管线化说明 -
其他特点
支持客户/服务器模式。支持基本认证和安全认证。
HTTP工作流程
- 首先客户机与服务器需要建立连接。只要单击某个超级链接,HTTP的工作开始。
- 建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URI)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。
- 服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
- 客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。
- HTTP是基于传输层的TCP协议,而TCP是一个端到端的面向连接的协议。所谓的端到端可以理解为进程到进程之间的通信。所以HTTP在开始传输之前,首先需要建立TCP连接,而TCP连接的过程需要所谓的“三次握手”
- 在TCP三次握手之后,建立了TCP连接,此时HTTP就可以进行传输了。一个重要的概念是面向连接,既HTTP在传输完成之间并不断开TCP连接。在HTTP1.1中(通过Connection头设置)这是默认行为。
HTTP请求和响应内容
请求报文示例
请求方法 请求URI 协议版本 - 请求行
[请求首部字段] - 报文首部
[通用首部字段] - 报文首部
[实体首部字段] - 报文首部
[其他] - 报文首部
空行(CR+LF)
[可选的请求内容实体] - 报文主体
请求报文是由请求方法、请求URI、协议版本、可选的请求首部字段和内容实体构成 、其他(可能包含HTTP的RFC里未定义的首部,例如cookie) 请求报文示例图如下:
响应报文示例
协议版本 状态码 原因短语 - 状态行
[响应首部字段] - 报文首部
[通用首部字段] - 报文首部www
[实体首部字段] - 报文首部
[其他] - 报文首部
空行(CR+LF)
[可选的响应内容实体] - 报文主体
响应报文是由协议版本、状态码、原因短语、可选的响应首部字段、其他(可能包含HTTP的RFC里未定义的首部,例如cookie)、可选的响应内容实体构成 响应报文示例图如下:
URI
- 指定请求URI的两种方法
- 在请求行中指定完整的请求URI
- GET http://www.jumei.com/index.html HTTP/1.1
- 在首部字段HOST写明网络域名或者IP地址
- GET /index.html HTTP/1.1
- HOST: www.jumei.com
- 在请求行中指定完整的请求URI
请求方法
1)HTTP/1.1协议中共定义了八种方法(有时也叫“动作”)来表明Request-URI指定的资源的不同操作方式
- OPTIONS- 返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送’*'的请求来测试服务器的功能性
- HEAD- 向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新
- GET- 向特定的资源发出请求。注意:GET方法不应当被用于产生“副作用”的操作中,例如在web app.中。其中一个原因是GET可能会被网络蜘蛛等随意访问。(主要就是python爬虫,可以爬数据)。
- POST- 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
- PUT- 向指定资源位置上传其最新内容。
- DELETE- 请求服务器删除Request-URI所标识的资源。(HTTP1.1支持)
- TRACE- 回显服务器收到的请求,主要用于测试或诊断。(HTTP1.1支持)
- CONNECT- HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。(HTTP1.1支持)
- PATCH- 用来将局部修改应用于某一资源,添加于规范RFC5789。
2)HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。此外,除了上述方法,特定的HTTP服务器还能够扩展自定义的方法。
3)方法名称是区分大小写的。当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Method Not Allowed);当服务器不认识或者不支持对应的请求方法的时候,应当返回状态码501(Not Implemented)。
GET和POST的区别
- 数据大小限制,GET提交的最多只能有2048字节(因为浏览器对URL的长度有限制,各浏览器也不近相同),而POST方法提交的数据没有限制。 需要说明的是,HTTP协议本身对URI没有长度限制,长度限制主要是由于浏览器或者服务器为了性能和安全做的限制。
- 数据格式限制,GET只允许ASCII码,POST没有限制,包括二进制数据也允许
- GET参数放在URI中,POST参数放在报文内容实体(body)中,在传输上都是使用TCP协议
- 单次请求的数据包,针对POST请求某些浏览器可能会先发送 header,服务端返回 100 状态码再发送 body,产生两个TCP数据包,但是只是某些浏览器可能会
首部
- 首部字段结构
- 每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。
- 端到端首部和逐跳首部
- End-to-end首部(端到端)
- 分在此类别中的首部会转发/响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须转发
- Hop-by-hop首部(逐跳)
- 分在此类别的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1和之后版本中,如果要使用hop-by-hop首部,需提供Connection首部字段
- 逐跳首部字段(除以下8个外都是端到端首部)
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transer-Encoding
- Upgrade #####首部类型
- End-to-end首部(端到端)
- HTTP常见的首部 在HTTP/1.1 协议中,所有的请求头,除Host外,都是可选的
- 通用首部字段(General Header Fields)
- 请求报文和响应报文双方都会使用的首部
- 首部字段
字段名 | 值 | 类型 | 说明 |
---|---|---|---|
Cache-Control | no-cache | 端到端首部 | 使用本地缓存之前,先请求服务器验证etag |
no-store | 端到端首部 | 彻底禁用缓存,每次都请求服务器,不验证etag | |
max-age=[秒] | 端到端首部 | 在max-age指定的时间之内,浏览器使用本地缓存,不会向服务器发送任何请求 | |
public | 端到端首部 | 可向任意方提供响应的缓存 | |
private | 端到端首部 | 仅向特定用户返回响应 | |
Connection | upgrade | 逐跳首部 | 不再转发的首部,该首部只转发一次 |
close | 端到端首部 | 管理持久链接,1.1默认开启持久链接,使用close关闭 | |
Keep-Alive | 端到端首部 | 管理持久链接,使用持久链接 | |
Date | Tue,03 Jul 2016 08:38:45 GMT | 端到端首部 | 创建报文的时间 |
Pragma | no-cache | 端到端首部 | HTTP/1.1之前都遗留字段,作为与HTTP/1.0的向后兼容,和Cache-Control:no-cache同时使用 |
Trailer | Expires | 逐跳首部 | 事先说明报文主体后记录了哪些首部字段 |
Transfer-Encoding | chunked | 逐跳首部 | 指定报文主体的传输编码方式,chunked分块编码,分块传输数据,最后一个块长度必须是0,对应的内容为空,表示传输结束 |
Upgrade | TLS/1.0 | 逐跳首部 | 升级为其他协议 |
Via | 1.0 gw.hackr.jp(Squid/3.1) | 端到端首部 | 代理服务器的相关信息,追踪请求/响应报文的传输路径 |
Warning | [警告码][警告的主机:端口号]“[警告内容]”(日期时间) | 端到端首部 | 通知与缓存相关的告警 |
- 请求首部字段(Request Header Fields)
- 客户端发送请求时使用的首部,补充了请求的附加内容、客户端信息、响应内容优先级等信息
- 首部字段
字段名 | 值 | 类型 | 说明 |
---|---|---|---|
Accept | text/plain,application/xhtml+xml | 端到端首部 | 通知服务器,用户代理可以处理的媒体类型及相对优先级 |
Accept-Charest | ios-8859-5,unicode-1-1;q=0.8 | 端到端首部 | 支持的字符集及优先级 |
Accept-Encoding | gzip,deflate,compress,identity | 端到端首部 | 支持的内容编码及优先级 |
Accept-Language | zh-cn,zh;q=0.7,en-us,en;q=0.3 | 端到端首部 | 支持的自然语言及优先级 |
Authorization | Basic dWVub3NlbjpwYXNzd29y | 端到端首部 | 告知服务器用户代理的认证信息 |
Expect | 100-continue | 端到端首部 | 期待服务器的特定行为 |
From | test@qq.com | 端到端首部 | 用户的电子邮箱地址 |
Host | www.jumei.com | 端到端首部 | 请求资源所在服务器和端口号,虚拟机IP相同必须通过主机名和端口区分 |
If-Match | If-Match:“123456” | 端到端首部 | 比较实体标记(ETag),例如只有etag=123456才执行请求 |
If-Modified-Since | Thu, 15 Apr 2016 00:00:00 GMT | 端到端首部 | 比较资源的更新时间,如果早于这个时间则服务器执行请求,否则返回状态码304 |
If-None-Match | If-None-Match: “123456” | 端到端首部 | 比较实体标记(与If-Match相反),etag不相等时执行请求 |
If-Range | If-Range:“123456”; Range: bytes=5001-10000 | 端到端首部 | 若指定的if-range字段值和请求资源的etag相同,则返回范围要求的资源,否则返回全部资源 |
If-Unmodified-Since | Thu, 15 Apr 2016 00:00:00 GMT | 端到端首部 | 比较资源的更新时间(与If-Modified-Since相反) |
Max-Forwards | Max-Forwards: 10 | 端到端首部 | 最大传输逐跳数,每次减1,为0时直接返回响应结果 |
Proxy-Authorization | basic dGlwOjkpNAd1LacW | 逐跳首部 | 代理服务器要求客户端的认证信息 |
Range | bytes=5001-10000 | 端到端首部 | 实体的字节范围请求,当返回范围资源时状态码为206,当返回全部资源时状态码为200 |
Referer | http://www.google.com | 端到端首部 | 对请求中URI的原始获取方 |
TE | gzip,deflate;q=0.5 | 逐跳首部 | 告知对方能处理的传输编码方式和优先级 |
User-Agent | Mozilla/5.0 (Windows NT 6.1) | 端到端首部 | 客户端程序的信息,包括浏览器和用户代理等信息 |
Origin | scheme://host:port | 端到端首部 | 描述请求来源地址 |
- 响应首部字段(Response Header Fields)
- 服务端响应请求时使用的首部,补充了响应的附加内容,也会要求客户端附加额外的内容信息
- 首部字段
字段名 | 值 | 类型 | 说明 |
---|---|---|---|
Accept-Ranges | bytes/none | 端到端首部 | 是否接受字节范围请求 |
Age | 600 | 端到端首部 | 告诉客户端,服务器在多久前创建了响应 |
Etag | “ea3cafs123vp912” | 端到端首部 | 资源的匹配信息etag,强etag,无论资源发生了多么细微的变化都会变化,弱etag,只有发生根本变化才会改变,值会在最开始处附加W/ |
Location | http://www.baidu.com | 端到端首部 | 令客户端重定向到指定URI |
Proxy-Authenticate | basic realm=“Usagidesign Auth” | 逐跳首部 | 代理服务器对客户端的认证信息 |
Retry-After | 120 | 端到端首部 | |
Server | Apache/2.2.17 | 端到端首部 | HTTP服务器程序的应用信息 |
Vary | vary: Accept-Lanuage | 端到端首部 | 代理服务器缓存的管理信息 |
WWW-Authenticate | Basic realm=“Usagidesign Auth” | 端到端首部 | 服务器对客户端的认证信息 |
- 实体首部字段(Entity Header Fields)
- 针对请求报文和响应报文的实体部分使用的首部,补充了资源内容更新时间等与实体有关的信息
- 首部字段
字段名 | 值 | 类型 | 说明 |
---|---|---|---|
Allow | GET,HEAD | 端到端首部 | 资源可支持的HTTP方法 |
Content-Encoding | gzip/compress/deflate/identity | 端到端首部 | 实体主体适用的编码方式 |
Content-Language | zh-cn | 端到端首部 | 实体主体的自然语言 |
Content-Length | 15000 | 端到端首部 | 实体主体的大小(单位:字节) |
Content-Location | http://www.baidu.com/baike/11 | 端到端首部 | 替代对应资源的URI,报文主体返回资源对应的URI |
Content-MD5 | OGFKZa1HsLiap9 | 端到端首部 | 实体主体的报文摘要,报文主体的MD5值 |
Content-Range | bytes 5001-10000/10000 | 端到端首部 | 实体主体的位置范围 |
Content-Type | text/html.charset=UTF-8 | 端到端首部 | 实体主体的媒体类型,和首部字段Accept一样,字段值用type/subtype形式赋值。 |
Expires | Web 04 Jul 2016 12:33:04 GMT | 端到端首部 | 实体主体过期的日期时间,后续请求缓存服务器根据此值决定是否使用缓存 |
Last-Modified | Web 04 Jul 2016 12:33:04 GMT | 端到端首部 | 资源的最后修改日期时间 |
- COOKIE首部字段
- 举例Set-Cookie:status=enable;expire=True,05 Jul 2011 07:26:31,具体说明如下
属性 | 说明 |
---|---|
NAME=VALUE | 赋予Cookie的名称和值(必需项) |
expires=DATE | Cookie的有效期(不指明则在浏览器关闭前有效) |
path=PATH | 将服务器上的文件目录作为Cookie的适用对象 |
domain=域名 | 作为COOKIE适用对象的域名 |
Secure | 仅在HTTPS安全通信时才会发送COOKIE |
HttpOnly | 加以限制,是COOKIE不能被JAVASCRIPT脚本访问 |
常见HTTP状态码
具体详见百度百科 《HTTP状态码》
- 1XX (代表请求已被服务器接受,需要继续处理)
- 100 continue
- 这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应
- 100 continue
- 2XX(代表请求已成功被服务器接收、理解、并接受)
- 200 OK
- 请求已成功,请求所希望的响应头或数据体将随此响应返回。出现此状态码是表示正常状态。
- 201 – Created 已创建
- 202 – Accepted 已接收
- 203 – Non-Authoritative Information 非权威内容
- 204 – No Content 没有内容
- 205 – Reset Content 重置内容
- 206 – Partial Content 服务器下发了部分内容(range header)
- 200 OK
- 3XX(重定向)
- 这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明
301和308,共同点 :资源被永久移动到新的地址,差异点:客户端收到308请求后,延用旧的method(POST/GET/PUT)到新地址,客户端收到301请求后,通常用户会向新地址发起GET请求
302/303/307,
共同点:资源临时放到新地址,
差异点:
- 302是http1.0提出的,最早叫做Moved Temporarily; 很多浏览器实现的时候没有遵照标准,把所有请求都重定向为GET
- 1999年标准委员会增加了303和307,并将302重新定义为Found。
- 303告诉客户端使用GET方法重定向资源
- 307告诉客户端使用原请求的method重定向资源
- 301 Moved Permanently
- 永久重定向,被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一
- 302 Move Temporarily
- 临时重定向,Found 资源被找到(以前是临时转移)
- 303 – See Other 可以使用GET方法在另一个URL找到资源
- 304 Not Modified
- 如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码
- 305 – Use Proxy 需要代理
- 307 – Temporary Redirect 临时重定向
- 308 – Permanent Redirect 永久重定向
- 这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明
- 4XX(客户端请求错误)
- 400 Bad Request
- 语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。
- 请求参数有误。
- 401 Unauthorized
- 当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。客户端可以重复提交一个包含恰当的 Authorization 头信息的请求。如果当前请求已经包含了 Authorization 证书,那么401响应代表着服务器验证已经拒绝了那些证书。
- 402 – Payment Required 请先付费
- 403 Forbidden
- 服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交
- 404 Not Found
- 请求失败,请求所希望得到的资源未被在服务器上发现
- 405 Method Not Allowed 方法不被允许
- 406 Not Acceptable 服务端可以提供的内容和客户端期待的不一样
- 413 Request Entity Too Large
- 服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。此种情况下,服务器可以关闭连接以免客户端继续发送此请求。
- 400 Bad Request
- 5XX(服务端处理错误)
- 500 Internal Server Error
- 服务器内部错误,服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。
- 501 – Not Implemented(没有实现)
- 502 Bad Gateway
- 网关错误,作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应
- 503 Service Unavailable
- 服务不可用,由于临时的服务器维护或者过载,服务器当前无法处理请求。
- 504 Gateway Timeout
- 网关超时,作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。
- 505 – HTTP Version Not Supported(版本不支持)
- 注意:某些代理服务器在DNS查询超时时会返回400或者500错误
- 500 Internal Server Error
HTTP的状态内容
补充概念
- 协议
- 指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。
- 报文
- 用于HTTP协议交互的信息被称为HTTP报文,客户端的叫请求报文,服务端返回的叫响应报文。
- 报文(message)是网络中交换与传输的数据单元,即站点一次性要发送的数据块。报文包含了将要发送的完整的数据信息,其长短很不一致,长度不限且可变
- 和HTTP相关的协议
- IP协议(网络层协议)
- TCP协议(传输层协议)
- DNS协议(域名系统,应用层协议) ARP协议
- COOKIE SESSION
- WEB安全
- http首部攻击
- 邮件首部攻击
- 会话劫持
keep-alive
作用:多次请求复用一个TCP连接。
示例:Keep-Alive: timeout=5, max=1000
为什么要keep-alive?
为了节省网络成本,会考虑多个请求复用一个TCP连接
keep-alive的断开
- 单个请求:请求完成后,在timeout时间内没第二个请求进来则会关闭。
- 多个请求:在一个请求响应之后,在 timeout 时间内有另一个请求进来,就会利用相同的 TCP 连接继续响应这个请求,直到没有更多请求进来,可以通过 max 字段设定最多响应的请求数。
keep-alive是不是长连接?
- keep-alive并不是长连接
- WebSocket:长连接,提供在HTTP协议退化成TCP协议的方式。让客户端和服务器之间保持很长时间的连接且不中断
系列文章