文章目录
HTTP协议
浏览器通过指定的访问地址(URL)获取(或上传)服务器资源(文件等信息)。
web服务器传输HTML…等数据到客户端(浏览器),其使用HTTP协议通信
Web使用一种名为HTTP(HyperText Transfer Protocol,超文本传输协议)的协议作为规范,完成从客户端到服务器端等一系列运作流程。WEB是建立在HTTP(TCP/80)协议上通信的(加密的HTTPS(TCP/443))。
HTTP是不保存状态的协议,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理。这是为了更快地处理大量事务。确保协议的可伸缩性,而特意把HTTP协议设计成如此简单的。
解决无状态:1.隐含参数(不太安全) 2.cookie
主要的两个HTTP METHOD方法GET、POST
GET vs POST
发送的请求符合以下任一条件时就应使用POST方法,都不符合时才使用GET方法。
- 请求中包含数据更新等副作用时
- 发送敏感信息时(防止Referer安全隐患)
- 发送的信息量很多时(URL长度有限)
副作用是指,除了获取资源(内容)以外的其它操作。比如,追加/更新/删除服务端的数据、购买商品、注册/删除用户等操作。换言之,更新类的页面必须使用POST方法。
PUT
该方法用来传输文件,就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置。但是,鉴于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般的WEB网站不使用该方法。若配合WEB应用程序的验证机制,或架构设计采用REST(REpresentational State Transfer,表征状态转移)标准的同类WEB网站,就可能会开放使用PUT方法,注意:一般文件上传依然采用POST。
HEAD
获取报文首部,和GET方法一样,只是不返回报文主体部分,用于确认URI的有效性及资源更新的日期时间等。
DELETE
该方法是用来删除文件,是与PUT相反的方法,DELETE方法按请求URI删除指定的资源。但是,HTTP/1.1的DELETE方法本身和PUT方法一样不带验证机制,所以一般的web网站也不使用DELETE方法。当配合web应用程序的验证机制,或遵循REST标准时还是有可能会开放使用的。
cookie
浏览器第一次请求服务器,服务器会生成cookie然后在响应中添加,后返回。
第二次请求服务器只需要把cookie放进请求中,就无需验证,接着服务器响应。
WWW的三项构建技术
- 页面的文本标记语言—HTML(HyperText Markup Language,超文本标记语言)
- 作为文档传递协议的HTTP
- 指定文档所在地址的URL(Uniform Resource Locator,统一资源定位符)
URI与URL
URI是Uniform Resource Identifier的缩写,RFC2396分别对这3个单词进行了如下定义:
- Uniform:规定统一的格式可方便处理不同类型的资源,而不用根据上下文环境来识别资源指定的访问方式。另外,加入了新增的协议方案(如http:或ftp)也更容易
- Resource:资源的定义是“可标识的任何东西”。除了文档文件、图像或服务(例如当天的天气预报)等能够区别于其它类型的,全部可作为资源。另外,资源不仅仅是单一的,也可以是多数的集合体。
- Identifier:表示可标识的对象。也称为标识符。
URI用字符串标识某一互联网资源,而URL表示资源的地点(互联网上所处的位置)。可见URL是URI的一个子集。
URL就是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。URI是以一种抽象的,高层次概念定义统一资源标识,而URL则是具体的资源标识的方式,URL就是URI的一种。
ftp://ftp.xxx.xx/xx/xx
http://ww.xxx.com/xxx/xx
ldap://[xxx:xxx::x]/xxxx
mailto:[email protected]
…
HTTP报文
用于HTTP协议交互的信息被称为HTTP报文。请求端(客户端)的HTTP报文叫做请求报文,响应端(服务器端)的叫做响应报文。HTTP报文本身是由多行(用CR+LF作换行符)数据构成的字符串文本。
HTTP报文大致可分为报文首部和报文主体两块,两者由最初出现的空行(CR+LF)来划分。通常,并不一定要有报文主体。
拆分 | 描述 |
---|---|
报文首部 | 服务器或客户端需处理的请求或响应的内容及属性 |
空行(CR+LF) | CR(Carriage Return,回车符:16进制0x0d)和LF(Line Feed,换行符:16进制0x0a) |
报文主体 | 应被发送的数据 |
HTTP状态码功能
状态码的职责是当客户端向服务端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。
状态码的类别
类别 | 原因短语 | |
---|---|---|
1XX | Information(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
- 200 OK
- 204 No Content
该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。比如,当从浏览器发出请求处理后,返回204响应,那么浏览器显示的页面不发生更新。
一般只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。 - 206 Partial Content
该状态吗表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Conten-Range指定范围的实体内容。 - 301 Moved Permanently
永久性重定向。该状态码表示请求的资源已被分配了新的URI。也就是说,如果已经把资源对应的URI保存为书签了,这时应该按Location首部字段提示的URI重新保存。 - 302 Moved Temporarily
临时性重定向。该状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问。 - 303 See Other
该状态码表示由于请求对应的字源存在着另一个URI,应使用GET方法定向获取请求的资源。
303状态码和302状态码有着相同的功能,但303状态码明确表示客户端应当采用GET方法获取资源,这点与302状态码有区别。
比如,当使用POST方法访问CGI程序,其执行后的处理结果是希望客户端能以GET方法重定向到另一个URI上去时,返回303状态码。虽然302状态码也可以实现相同的功能,但这里使用303状态码是最理想的。 - 304 Not Modified
该状态码表示客户端发送附带条件的请求A时,服务器端允许请求访问资源,但未满足条件的情况。304状态码返回时,不包含任何响应的主体部分。304虽然被划分在3XX类别中,但是和重定向没有关系。 - 307 Temporary Redirect
临时重定向。该状态码与302有着相同的含义。尽管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
该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入Retry-After首部字段再返回给客户端。
HTTP报文首部
报文首部:在客户端和服务器处理时起至关重要作用的信息几乎都在这边。
空行(CR+LF)
报文主体:所需要的用户和资源的信息都在这边。
HTTP首部字段是构成HTTP报文的要素之一。在客户端与服务器之间以HTTP协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。
使用首部字段是为了个浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
首部字段是由首部字段名和字段值构成,中间用“:”分隔。
首部字段名: 字段值
Content-Type: text/html
4种首部字段类型
- 通用首部字段(General Header Fields):请求报文和响应报文两方都会使用的首部
- 请求首部字段(Request Header Fields):从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息
- 响应首部字段(Response Header Fields):从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
- 实体首部字段(Entity Header Fields):针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
通用首部字段表
通用首部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存的行为 |
Connection | 逐跳首部、连接的管理 |
Date | 创建报文的日期时间 |
Pragma | 报文指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其它协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
Cache-Control
通过指定首部字段Cache-Control的指令,就能操作缓存的工作机制。
指令的参数是可选的,多个指令之间通过“,”分隔。首部字段Cache-Control的指令可用于请求及响应时。
Cache-Control: private, max-age=0, no-cache
Connection
HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此,如果想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段值为Kepp-Alive
Connection: Keep-Alive
HTTP/1.1版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定Connection首部字段的值为Close。
Connection: Close
Date
首部字段Date表明创建HTTP报文的日期和时间
Transfer-Encoding
首部字段Transfer-Encoding规定了传输报文主体时采用的编码方式
有效使用分块(chunked)传输编码,且分别被分成多少多少字节大小的分块数据。
Upgrade
首部字段Upgrade用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
Warning
HTTP/1.1的Warning首部是从HTTP/1.0的响应首部(Retry-After)演变过来的。该首部通常会告知用户一些与缓存相关的问题警告。
Warning首部的格式如下。最后的日期时间部分可省略:
Warning: [警告码] [警告的主机:端口号] "[警告的内容]" ([日期时间])
请求首部字段表
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
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 | 对请求中URI的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP客户端程序的信息 |
Accept
Accept首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用type/subtype这种形式,一次指定多种媒体类型。
Accept: text/html, application/xhtml+xml, application/xml;q=0.9,*/*;q=0.8
若想要给显示的媒体类型增加优先级,则使用q=来额外表示权重值,用分号(;)进行分隔。权重值q的范围是0~1(可精确到小数点后3位),且1为最大值。不指定权重q值时,默认权重为q=1.0。
当服务器提供多种内容时, 将会首先返回权重值最高的媒体类型。
Accept-Charset
可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段Accept相同的是可用权重q值来表示相对优先级。
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
Accept-Encoding
用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。
Accept-Encoding: gzip, deflate
Accept-Language
用来告知服务器用户代理能够处理的自然语言集(指定中文或英文等),以及自然语言集。和Accept首部字段一样,按权重值q来表示相对优先级。
Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3
Authorization
用来告知服务器,用户代理的认证信息(证书值)。通常,想要通过服务器认证的用户代理会在接收到返回的401状态码响应后,把首部字段Authorization加入请求中。
Host
会告知服务器,请求的资源所处的互联网主机名和端口号。Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段。
首部字段Host和以单台服务器分配多个域名的虚拟主机的工作机制有密切的关联,这是首部字段Host必须存在的意义。
Referer
会告知服务器请求的原始资源的URI。
客户端一般都会发送Referer首部字段给服务器。但当直接在浏览器的地址栏输入URI,或出于安全性的考虑时,也可以不发送该首部字段。
User-Agent
会将创建请求的浏览器和用户代理名称等信息传达给服务器。
响应首部字段
首部字段名 | 说明 |
---|---|
Accent-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过时间 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定的URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
Location
使用首部字段Location可以将响应接收方引导至某个与请求URI位置不同的资源。
基本上,该字段会配合3xx: Redirection 的响应,提供重定向URI。
几乎所有的浏览器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源访问。
Server
告知客户端当前服务器上安装的HTTP服务器应用程序的信息。不单单会标出服务器上的软件应用名称,还有可能包括版本号和安装时启用的可选项。
Server: Apache/2.2.17 (Unix)
Server: Apache/2.2.6 (Unix) PHP/5.2.5
修复Server安全问题
/etc/php.ini
修改
expose_php = Off
/etc/httpd/conf/httpd.conf
添加
ServerToken Prod
WWW-Authenticate
用于HTTP访问认证。它会告知客户端适用于访问请求URI所指定资源认证方案(Basic或Digest)和带参数提示的质询(challenge)。状态码401 Unauthorized响应中,肯定带有首部字段WWW-Authenticate。
WWW-Authenticate: Basic realm="Usagidesign Auth"
实体首部字段表
首部字段名 | 说明 |
---|---|
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体适用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体的大小(单位:字节) |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体主体的报文摘要 |
Content-Range | 实体主体的位置范围 |
Content-Type | 实体主体的媒体类型 |
Expires | 实体主体过期的日期时间 |
Last-Modified | 资源的最后修改日期时间 |
Allow
用于通知客户端能够支持Request-URI指定资源的所有HTTP方法。当服务器接收到不支持的HTTP方法时,会以状态码405 Method Not Allowed作为响应返回。与此同时,还会把所有能支持的HTTP方法写入首部字段Allow后返回。
Allow: GET, HEAD
Content-Encoding
会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下进行的压缩。
Content-Language
会告知客户端,实体主体使用的自然语言(指中文或英文等语言)
Content-Language: zh-CN
Content-Length
表明实体主体部分的大小(单位是字节)
Content-Length: 15000
Content-Location
给出与报文主体部分相对应的URI。和首部字段Location不同。Conten-Location表示的是报文主体返回资源对应的URI。
比如对于使用首部字段Accept-Language的服务器驱动型请求,当返回的页面内容与实际请求的对象不同时,首部字段Content-Location内会写明URI
Content-Location: http://www.hackr.jp/index-ja.html
Content-Type
说明了实体主体内对象的媒体类型。和首部字段Accept一样,字段值用type/subtype形式赋值。
参数charset使用iso-8859-1或euc-jp等字符集进行赋值。
Content-Type: text/html; charset=UTF-8
Expires
会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。
Expires: Wed, 04 Jul 2020 21:45:09 GMT
为Cookie服务的首部字段
首部字段名 | 说明 | 首部类型 |
---|---|---|
Set-Cookie | 开始状态管理所使用的Cookie信息 | 响应首部字段 |
Cookie | 服务器接收到的Cookie信息 | 请求首部字段 |
Cookie相关:Set-Cookie
当服务器准备开始管理客户端的状态时,会事先告知各种信息。
Set-Cookie: status=enable; expires=Tue, 06 Jul 2020 01:55:13 GMT; => path=/; domain=.hackr.jp;
属性 | 说明 |
---|---|
NAME=VALUE | 赋予Cookie的名称和其值(必需项) |
expires | Cookie的有效期(若不明确指定则默认为浏览器关闭为止) |
path=PATH | 将服务器上的文件目录作为Cookie的使用对象(若不指定则默认为创建Cookie的服务器的域名 |
Secure | 仅在HTTPS安全通信时才会发送Cookie |
HttpOnly | 加以限制,使Cookie不能被JavaScript脚本访问 |