HTTP的一些理解

URI是Uniform Resource Identifier的缩写,统一资源标识符。URI用字符串标识某一互联网资源,而URL标识资源的地点(互联网上所处的位置)。可见URL是URI的子集。
典型的例子有:

ftp://www.ietf.org/RFC/RFC2396.txt
mailto:John.Doe@example.com
telnet://192.0.2.16:8000/

URI格式

表示指定的URI,要使用涵盖全部必要细腻的绝对URI、绝对URL以及相对URL。相对URL是指从浏览器中基本URI出指定的URL,形如/image/logo.gif
绝对URI的格式:http://user:pass@www.example.jp:80/dir/index.htm?uid=1#ch1
协议方案名:http://
使用http:或https:等协议方案名获取访问资源时要制定协议类型。不区分字母大小写,最后附一个冒号。
登录信息:user:pass
指定用户名和密码作为从服务器端获取资源必要的登录信息,此项为可选项。
服务器地址:www.example.jp
使用绝对URI必须指定待访问的服务器地址,地址可以使类似hackr.jp这种DNS可解析的名称,或者是192.168.0.1的IPv4地址,也可以是IPv6地址。
服务器端口号: :80
带层次的文件路径:/dir/index.htm?
指定服务器上的文件路径来定位特定的资源,这与UNIX系统的文件努力结构相似。
查询字符串:uid=1
针对已指定的文件路径内的资源,可以使用查询字符串传入任意参数。
片段标识符:#ch1
使用片段标识符通常可标记处已获取资源中的子资源。

HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。
客户端的请求报文

GET /index.htm HTTP/1.1
Host:hack.jp

GET是请求访问服务器的类型,称为方法。随后的字符串/index.htm指明了请求访问的资源对象,也叫做请求URI。HTTP/1.1是HTTP的版本号。
请求报文是由请求方法+请求URI+协议版本+可选的请求首部字段和内容实体构成的,这点在python中的requests上会有较深的体会,此外在获取网站的API的时候,网站也会告诉你请求的格式,这些都属于请求报文的范畴。

响应报文是由协议版本、状态码(表示请求成功200或失败502、404、400..的数字代码)、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成。

使用HTTP协议,每当有新的请求就会有新的响应产生,协议本身不会保留之前的请求或响应报文的信息。这是为了更快的处理大量事务、确保协议的可伸缩性而特意设计的。但是如果我们在写程序模拟登录的时候,网页会自动分配一个"工作流水号",这样子模拟登录的时候就不知道新的工作流水号从而导致模拟登录失败。HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了Cookie技术。

方法 说明 支持的HTTP协议版本
GET 获取资源 1.0、1.1
POST 传输实体主体 1.0、1.1
PUT 传输文件 1.0、1.1
HEAD 获得报文首部 1.0、1.1
DELETE 删除文件 1.0、1.1
OPTIONS 询问支持的方法 1.1
TRACE 追踪路径 1.1
CONNECT 要求用隧道协议连接代理 1.1
LINK 建立和资源之间的联系 1.0
UNLINE 断开连接关系 1.0

获取部分内容的范围请求:响应返回状态码为206Partial Content的响应报文

内容协商技术:

这个技术讲的是,同一个网站的页面可能存在多种形式,比如谷歌的网站面对不同国家会有不同的语言页面形式;当客户端请求的时候,报文中会包含浏览器的一些参数,报文会将这些参数和服务器进行协商,协商过后会返回浏览器能识别的内容。
服务器驱动协商(Server-driven Negotiation)
由服务器端进行内容协商。以请求的首部字段为参考,在服务器端自动处理。但对用户来说,以浏览器发送
的信息作为判定的依据,并不一定能筛选出最优内容。
客户端驱动协商(Agent-driven Negotiation)
由客户端进行内容协商的方式。用户从浏览器显示的可选项列表中手动选择。还可以利用 JavaScript 脚本在
Web 页面上自动进行上述选择。比如按 OS 的类型或浏览器类型,自行切换成 PC 版页面或手机版页面。
透明协商(Transparent Negotiation)
是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行内容协商的一种方法。

状态码

状态码如200 OK,以3位数字和原因短语组成;数字中的第一位制定了响应类别,后两位五分类。响应类别有以下5种:

类别 原因短语
1XX Informational(信息性状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作已完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错
下面介绍一些常用的14种状态码:
200 OK:表示从客户端发来的请求在服务器端被正常处理了。
204 No Content:代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。比如,当从浏览器发出请求处理后,返回 204 响应,那么浏览器显示的页面不发生更新。
206 Partial Content:表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range 指定范围的实体内容。
301 Moved Permanently:永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。也就是说,如果已经把资源对应的 URI 保存为书签了,这时应该按 Location 首部字段提示的 URI 重新保存。
302 Found:临时性重定向。该状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的 URI访问。与301不同的是,302表示临时更改,所以客户端不会更新原先的URI,同时
也会保存新的URI。
303 See Other:该状态码表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。与302的功能是相同的,所不同的是明确告诉客户端利用GET方法去请求资源。虽然 RFC 1945 和 RFC 2068 规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将 302 响应视为 303 响应,并且使用 GET 方式访问在Location 中规定的 URI,而无视原先请求的方法。所以使用 303 是最理想的
304 Not Modified:表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况。304状态码返回时,不包含任何响应的主体部分。304虽然被划分在3XX类别中,但是和重定向没有关系。
307 Temporary Redirect:临时重定向。该状态码与 302 Found 有着相同的含义。尽管 302 标准禁止 POST 变换成 GET,但实际使用时大家并不遵守。307 会遵照浏览器标准,不会从 POST 变成 GET。但是,对于处理响应时的行为,每种浏览器有可能出现不同的情况。
400 Bad Request:该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。另外,浏览器会像 200 OK 一样对待该状态码。
401 Unauthorized:该状态码表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示用 户认证失败。返回含有 401的响应必须包含一个适用于被请求资源的 WWW-Authenticate首部用以质询(challenge)用户信息。当浏览器初次接收到401响应,会弹出认证用的对话窗口。
403 Forbidden:该状态码表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源IP地址试图访问)等列举的情况都可能是发生 403 的原因。
404 Not Found:该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。
500 Internal Server Error:该状态码表明服务器端在执行请求时发生了错误。也有可能是 Web 应用存在的bug或某些临时的故障。
503 Service Unavailable:该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好可以写入 RetryAfter 首部字段再返回给客户端。

通信数据转发程序:代理、网关、隧道

这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给客户端。
代理:
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。
网关:
网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。
隧道:
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。
代理有多种使用方法,按两种基准分类。一种是是否使用缓存,另一种是是否会修改报文。
1.缓存代理
代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上。当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回。
2.透明代理
转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理(Transparent Proxy)。反之,对报文内容进行加工的代理被称为非透明代理。
网关
网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提供非 HTTP 协议服务。
利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。比如,网关可以连接数据库,使用 SQL语句查询数据。
隧道
隧道可按要求建立起一条与其他服务器的通信线路,届时使用 SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。
隧道本身不会去解析 HTTP请求。也就是说,请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。

4 种 HTTP 首部字段类型

HTTP 首部字段根据实际用途被分为以下 4 种类型。
通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。
请求首部字段(Request Header Fields)
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
响应首部字段(Response Header Fields)
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
实体首部字段(Entity Header Fields)
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。

Cache

Cache分为public、private、no-cache,从字面上理解就是缓存可以供其他客户端使用、缓存只给指定的客户端使用、no-cache为不允许存储过期的缓存(do-not-serve-from-cache-without-revalidation)。
使用 no-cache 指令的目的是为了防止从缓存中返回过期的资源。
客户端发送的请求中如果包含 no-cache 指令,则表示客户端将不会接收缓存过的响应。于是,“中间”的缓存
服务器必须把客户端请求转发给源服务器。
如果服务器返回的响应中包含 no-cache 指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。
应用 HTTP/1.1 版本的缓存服务器遇到同时存在 Expires 首部字段的情况时,会优先处理 max-age 指令,而忽略掉 Expires 首部字段。

请求首部字段

Accept

Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用type/subtype 这种形式,一次指定多种媒体类型。

Accept-Charset

Accept-Charset首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段 Accept 相同的是可用权重 q值来表示相对优先级。
该首部字段应用于内容协商机制的服务器驱动协商。

Accept-Encoding

Accept-Encoding首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。

Authorization

首部字段 Authorization是用来告知服务器,用户代理的认证信息(证书值)。通常,想要通过服务器认证的
用户代理会在接收到返回的 401状态码响应后,把首部字段 Authorization 加入请求中。共用缓存在接收到含有 Authorization 首部字段的请求时的操作处理会略有差异。

Except

客户端告诉服务器期望出现的某种特定行为。

From

首部字段 From用来告知服务器使用用户代理的用户的电子邮件地址。通常,其使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。使用代理时,应尽可能包含 From 首部字段(但可能会因代理不同,将电子邮件地址记录在 User-Agent 首部字段内)。

Host

虚拟主机运行在同一个IP上,因此使用首部字首部字段 Host 会告知服务器,请求的资源所处的互联网主机名和端口号。Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请求内的首部字段。
首部字段 Host和以单台服务器分配多个域名的虚拟主机的工作机制有很密切的关联,这是首部字段 Host 必须存在的意义。请求被发送至服务器时,请求中的主机名会用 IP地址直接替换解决。但如果这时,相同的 IP 地址下部署运行着多个域名,那么服务器就会无法理解究竟是哪个域名对应的请求。因此,就需要使用首部字段 Host 来明确指出请求的主机名。若服务器未设定主机名,那直接发送一个空值即可。Host加以区分。

Max-Forwards

每经过一个主机或者路由或者代理服务器,转发数值减1.通过 TRACE 方法或 OPTIONS 方法,发送包含首部字段 Max-Forwards 的请求时,该字段以十进制整数形式
指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,Max-Forwards 的值减 1 后重新赋
值。当服务器接收到 Max-Forwards 值为 0 的请求时,则不再进行转发,而是直接返回响应。
但是这种机制,如果在转发过程中遇到循环或者报文丢失,就会导致客户端收不到响应。

User-Agent

首部字段 User-Agent会将创建请求的浏览器和用户代理名称等信息传达给服务器。

响应首部字段

Accept-Ranges

首部字段 Accept-Ranges是用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。

Age

首部字段Age能告知客户端,源服务器在多久前创建了响应;字段值的单位为秒。

ETag

首部字段 ETag能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag 值。
P.S:当资源更新是,ETag值也需要更新。生成ETag时是由服务器随意分配得出的。

实体首部字段

Allow

首部字段 Allow 用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回。

Content-Encoding

首部字段 Content-Encoding 会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩。

Expires

首部字段 Expires 会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段 Expires 的响应后,会以缓存来应答请求,在 Expires 字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。

为Cookie服务的首部字段

Cookie 的工作机制是用户识别及状态管理。Web 网站为了管理用户的状态会通过 Web 浏览器,把一些数据
临时写入用户的计算机内。接着当用户访问该Web网站时,可通过通信方式取回之前发放的 Cookie。
调用 Cookie 时,由于可校验 Cookie的有效期,以及发送方的域、路径、协议等信息,所以正规发布的Cookie 内的数据不会因来自其他 Web 站点和攻击者的攻击而泄露。

首部字段名 说明 首部类型
Set-Cookie 开始状态管理所使用的Cookie信息 响应首部字段
Cookie 服务器接收到的Cookie信息 请求首部字段
一旦Cookie从服务器端发送至客户端,服务器端就不存在可以显式删除Cookie的方法,但可以通过覆盖已过期的Cookie,实现对客户端Cookie实质性删除操作。

其他首部字段

HTTP 首部字段是可以自行扩展的。所以在 Web 服务器和浏览器的应用上,会出现各种非标准的首部字段。
接下来,我们就一些最为常用的首部字段进行说明。

  • X-Frame-Options
  • X-XSS-Protection
  • DNT
  • P3P

首部字段 X-Frame-Options 属于 HTTP响应首部,用于控制网站内容在其他 Web 网站的 Frame 标签内的显示问题。其主要目的是为了防止点击劫持(clickjacking)攻击。

首部字段 X-XSS-Protection 属于 HTTP 响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关。

首部字段 DNT 属于 HTTP 请求首部,其中 DNT 是 Do Not Track 的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。

首部字段 P3P 属于 HTTP 相应首部,通过利用 P3P(The Platform for Privacy Preferences,在线隐私偏好
平台)技术,可以让 Web网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。

以上字段可以参照下面的代码进行配置:

<IfModule mod_headers.c>
Header append X-FRAME-OPTIONS "SAMEORIGIN"
</IfModule>
posted @ 2018-01-31 23:19  MrYun  阅读(282)  评论(0编辑  收藏  举报