HTTP学习
URI 和 URL
URI:统一资源标识符(英语:Uniform Resource Identifier,URI)是一个用于标识某一互联网资源名称的字符串, 该种标识允许用户对网络中(一般指万维网)的资源通过特定的协议进行交互操作。URI的最常见的形式是统一资源定位符(URL),经常指定为非正式的网址。更罕见的用法是统一资源名称(URN),其目的是通过提供一种途径。用于在特定的名字空间资源的标识,以补充网址。
URL:统一资源定位符(或称统一资源定位器/定位地址、URL地址等,时也被俗称为网页地址(网址).英语:Uniform Resource Locator,常缩写为URL)
以上摘自维基百科
URI的格式
scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
URI文法由URI协议名(例如“http”,“ftp”,“mailto”或“file”),一个冒号,和协议对应的内容所构成。特定的协议定义了协议内容的语法和语义,而所有的协议都必须遵循一定的URI文法通用规则,亦即为某些专门目的保留部分特殊字符。
URI的格式
协议类型:[//[访问资源需要的凭证信息@]服务器地址[:端口号]][/资源层级UNIX文件路径]文件名[?查询][#片段ID]
其中【访问凭证信息@;:端口号;?查询;#片段ID】都属于选填项。
http://zh.wikipedia.org:80/w/index.php?title=a
1. http,是协议;
2. zh.wikipedia.org,是服务器;
3. 80,是服务器上的网络端口号;
4. /w/index.php,是路径;
5. ?title=a,是询问字段
由于超文本传输协议允许服务器将浏览器重定向到另一个网页地址,因此许多服务器允许用户省略网页地址中的部分,比如 www。从技术上来说这样省略后的网页地址实际上是一个不同的网页地址,浏览器本身无法决定这个新地址是否通,服务器必须完成重定向的任务。
以上摘自维基百科
报文
报文的组成:
- 请求行,例如:GET /logo.gif HTTP/1.1或状态码行,例如:HTTP/1.1 200 OK,
- HTTP头字段
- 空行
- 可选的HTTP报文主体数据
请求报文
包括方法、URL、HTTP版本、HTTP等首部字段等部分
<method><request-URL><version> // GET / HTTP/1.1
<headers>
<entity-body>
响应报文
包括HTTP版本、状态码、HTTP首部字段
<version><status><reason-phrase> // HTTP/1.1 304 NOT MODIIED
<headers>
<entity-body>
注意请求行的区别
首部字段
大部分信息都包含在首部字段里,请求和响应均有首部字段,可以为浏览器和服务器提供报文主体大小,使用的语言,认证信息等内容
结构
首部字段名: 字段值
类型
类型分为4种,每种又有多个字段名,每个字段名对应多个字段值。这里将会记录几个常用的指令,以供查阅。
通用首部字段
字段名 | 说明 |
---|---|
Cache-Control | 控制缓存行为 |
Connection | 服务器和客户端是否保持连接或者逐跳首部的连接 |
Date | 报文创建日期和时间 |
Via | 显示了报文经过的中间节点 |
Upgrade | 升级为其他协议 |
Trailer | 如果报文采用分块传输编码方式,可以利用这个首部列出位于报文trailer部分的首部集合 |
Pragma | 早期的随报文传送指示方式 |
Transfer-Encoding | 告诉接收端对报文采用什么编码格式 |
Warning | 错误通知 |
请求首部字段
字段名 | 说明 |
---|---|
Accept | 通知服务器用户可以处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言 |
Expect | 期待服务器的特定行为 |
Host | 请求资源所在的服务器 |
From | 用户的电子邮箱地址 |
If-Match | 如果ETag和资源当前ETag匹配,就获取资源 |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 如果ETag和当前文档ETag不符合,获取资源 |
If-Range | 允许对文档否个范围内的条件请求 |
If-Unmodified-Since | 在某个指定日期之后没有修改过,否则现在请求 |
Referer | 提供了包含当前请求URI的文档的URL,告诉服务器自己来源 |
Client-IP | 客户端IP |
响应首部字段
首部字段名 | 说明 |
---|---|
Age | 响应持续时间 |
Server | 服务器应用软件名称和版本 |
Allow | 列出了可用的请求方法 |
Location | 告诉客户端实在在哪里,用于定向 |
Content-Base | 解析主体中相对URL的基础URL |
Content-Encoding | 主体编码格式 |
Content-Language | 解析主体时适用的语言 |
Content-Length | 主体的长度或尺寸 |
Content-Location | 资源实际位置 |
Content-MD5 | 主体的MD5校验和 |
Content-Range | 在整个资源中此实体部分的字节范围 |
Content-Type | 主体的MIME |
ETag | 主体的实体标记 |
Expires | 过期时间 |
Last-Modified | 实体最后一次修改时间 |
常用字段及其字段值详细介绍
Cache-Control:
-
Public表示响应可被任何中间节点缓存,如 Browser <-- proxy1 <-- proxy2 <-- Server,中间的proxy可以缓存资源,比如下次再请求同一资源proxy1直接把自己缓存的东西给 Browser 而不再向proxy2要。
-
Private表示中间节点不允许缓存,对于Browser <-- proxy1 <-- proxy2 <-- Server,proxy 会老老实实把Server 返回的数据发送给proxy1,自己不缓存任何数据。当下次Browser再次请求时proxy会做好请求转发而不是自作主张给自己缓存的数据。
-
no-cache表示不使用 Cache-Control的缓存控制方式做前置验证,而是使用 Etag 或者Last-Modified字段来控制缓存
-
no-store ,真正的不缓存任何东西。浏览器会直接向服务器请求原始文件,并且请求中不附带 Etag 参数(服务器认为是新请求)。
-
max-age,表示当前资源的有效时间,单位为秒。
Host:同一个ip可能有多个域名,当请求发送到服务器时,请求中的主机名会被使用ip替换,从而并不知道请求的主机是谁,Host可以设定请求的主机名
下面的if请求首部字段在条件为真时,才会执行请求
If-Match:
If-Match:'12345'
只有当字段值和Etag值匹配时,服务器接受请求,当使用 *
号作为字段值时,服务器忽略Etag 值,只要有资源存在就会对请求进行处理
If-Modified-Since
If-Modified-Since: Mon,10 Dec 2000 02:25:22GMT
在字段指定的时间后,资源发生了更新则处理请求,如果没有更新则返回304
If-None-Match
If-None-Match: *
当字段值与被请求资源Etag不同时处理请求,为 *
时是当资源不存在时响应改请求
Expires
Expires: Mon,10 Dec 2018 02:25:22GMT
服务端将资源有效期带上发送给客户端,缓存到本地,当再次发请求时用浏览器事件与其进行比较决定是否使用缓存文件。Cache-Control
的 Max-age
优先级大于 Expires
,与 max-age
区别这个是服务器给了它一个失效日期,而max-age
设置的秒数
Last-Modified
Last-Modified: Mon,10 Dec 2018 02:25:22GMT
指明资源最终被修改的事件,一般是请求的资源被修改的事件,但是某些情况下资源被修改则会改变
Etag
服务器为资源分配的尸体标识,当资源内容更新时,Etag也更新。比如当你访问同网站下的不同语言类型网页,这个网页的URL时相同的但是对应资源不同,可以通过它进行区分,又比如当你获取某个资源后,缓存时间到期后重新发起请求时需要判断资源内容是否变化,可以使用 Etag
,资源对应的Etag值唯一的。
这里又分为强 Etag
和弱 Etag
强 Etag
会在发生任何改变均会改变 Etag
的值
Etag: '12345'
弱 Etag
用于提升为资源是否相同,当资源发生根本改变,才会改变 Etag
的值。
Etag: W/'12345'
cookie
Set-Cookie
响应首部字段
服务器返回的Cookie信息
属性 | 说明 |
---|---|
NAME=VALUE | 为Cookie添加名称和值 |
expires = DATE | Cookie的有效期 |
path = PATH | 限定指定的Cookie发送的范围 |
domain=域名 | 对指定的域名发送Cookie |
Secure | 仅在HTTPS时发送Cookie |
HttpOnly | 使Cookie不被JavaScript访问 |
Cookie
请求首部字段
服务器接收到的Cookie信息
浏览器如何控制缓存
例如:
当浏览器请求一个图片 img.png时,服务器发送完整的文件并带上 Etag
,并设置资源有效期
Cache-Control: max-age=300;
ETag:W/"ad/scd"
浏览器将图片缓存到本地,当浏览器在300s以内再次请求该图片,浏览器会从缓存中读取次图片,当过了有效期后再次请求图片时,请求会带上 Etag
值,服务器在接收到请求后检查 Etag
值If-None-Match: W/"ad/scd
,此值为真则会发送新的文件和 Etag
,否则返回 304.
总结:
服务器响应设置有效期:Cache-Control:max-age
和 Expires
Expires
设置的时间是一个绝对时间,所以当客户端的时间被修改后就会影响它的期限效果
Cache-Control:max-age
时相对时间,都是相对于客户端时间判断
判断资源是否更新:
-
Last-Modified 和 If-Modified-Since
服务器会响应一个Last-Modified字段, 表示资源最近一次修改缓存的时间, 当缓存过期后, 浏览器就会把这个时间放在If-Modified-Since去请求服务器, 判断缓存是否有更新 -
Etag和If-None-Match
服务器会响应一个Etag字段, 一个表示文件唯一的字符串, 一旦文件更新, Etag也会跟着更改, 当缓存过期后, 浏览器会把这个字符串放在If-None-Match去请求服务器, 判断是否有更新, Etag的优先级比Last-Modified的更高, Etag的出现, 是为了解决一个缓存文件在短时间内被多次修改的问题, 因为Last-Modified只能精确到秒
这两种机制可以同时启用
参考详细原地址见文章评论处
请求类型
GET
获取资源,比如获取 网页
POST
向服务器发送数据,比如表单数据
HEAD
和GET类似,但是返回的响应中没有报文主体(即资源内容),只有一些基本信息
可用来
1.在不获取资源的情况下获取资源信息(类型、大小等)
2.通过状态码产看资源是否存在
3.通过查看首部,测试资源是否被修改了
PUT
向服务器写入资源,比如传输文件,请求报文中需要包含报文主体,将内容保存到请求URI指定的位置,PUT的语义就是让服务器用请求的主体部分创建一个请求URI命名的文档,如果存在就替换。
TRACE
追踪路径,可以通过它查询发送的请求是否被修改,不常用因为会引起XST攻击
OPTIONS
用来查询针对请求URL指定的资源所支持的方法
DELETE
删除请求URI指定的资源
附上一篇关于GET和POST的区别的文章
下面简单总结文章中几个区别:
-
get时获取资源,Post 时发送资源分贝对应“增删改查”的查和改
-
get 会将数据拼接到URL上,这对服务器会造成很大的负担,而post则是放在request body 上,都没有绝对的安全。
-
get 发送数据长度大小并不是因为浏览器限制,而是因为服务器限制后让浏览器可能限制长度也可能不限制长度,post 的数据大小则取决于服务器的处理性能
要知道任何人的文章都有可能出错,如何分辨,如何吸收全取决于自己
附上状态码:
- 100-199
这一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束
- 200-299
这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。
- 300-399
用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。这类状态码代表需要客户端采取进一步的操作才能完成请求。
- 400-499
用于指出客户端的错误。这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。
- 500-599
服务器错误。表示服务器无法完成明显有效的请求。
状态码 | 状态信息 | 含义 |
---|---|---|
100 | Continue | 初始的请求已经接受,客户应当继续发送请求的其余部分 |
200 | OK | 一切正常,对GET和POST请求的应答文档跟在后面。在GET请求中,响应将包含与请求的资源相对应的实体。在POST请求中,响应将包含描述或操作结果的实体。 |
201 | Created | 服务器已经创建了文档,Location头给出了它的URL。 |
202 | Accepted | 已经接受请求,但处理尚未完成。 |
203 | Non-Authoritative Information | 文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝 |
204 | No Content | 服务器成功处理了请求,没有返回任何内容。没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。 |
205 | Reset Content | 没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容 |
206 | Partial Content | 客户发送了一个带有Range头的GET请求,服务器完成了它(HTTP 1.1新) |
300 | Multiple Choices | 客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在Location应答头指明。 |
301 | Moved Permanently | 客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。 |
302 | Found | 类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。注意,在HTTP1.0中对应的状态信息是“Moved Temporatily”。出现该状态代码时,浏览器能够自动访问新的URL,因此它是一个很有用的状态代码。注意这个状态代码有时候可以和301替换使用。例如,如果浏览器错误地请求http://host/~user(缺少了后面的斜杠),有的服务器 返回301,有的则返回302。严格地说,我们只能假定只有当原来的请求是GET时浏览器才会自动重定向。请参见307。 |
303 | See Other | 类似于301/302,不同之处在于,如果原来的请求是POST,Location头指定的重定向目标文档应该通过GET提取 |
304 | Not Modified | 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告 诉客户,原来缓冲的文档还可以继续使用。 |
305 | Use Proxy | 客户请求的文档应该通过Location头所指明的代理服务器提取 |
307 | Temporary Redirect | 和302 (Found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是POST,即使它实际上只能在POST请求的应答是303时才能重定 向。由于这个原因,HTTP 1.1新增了307,以便更加清除地区分几个状态代码:当出现303应答时,浏览器可以跟随重定向的GET和POST请求;如果是307应答,则浏览器只 能跟随对GET请求的重定向。 |
400 | Bad Request | 请求出现语法错误 |
401 | Unauthorized | 客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填 写合适的Authorization头后再次发出请求 |
403 | Forbidden | 资源不可用。服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致。 |
404 | Not Found | 无法找到指定位置的资源。这也是一个常用的应答。 |
405 | Method Not Allowed | 请求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)对指定的资源不适用 |
406 | Not Acceptable | 指定的资源已经找到,但它的MIME类型和客户在Accpet头中所指定的不兼容 |
407 | Proxy Authentication Required | 类似于401,表示客户必须先经过代理服务器的授权。 |
408 | Request Timeout | 在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。 |
409 | Conflict | 通常和PUT请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。 |
500 | Internal Server Error | 服务器遇到了意料不到的情况,不能完成客户的请求 |
501 | Not Implemented | 服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的PUT请求 |
502 | Bad Gateway | 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答 |
503 | Service Unavailable | 服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个 Retry-After头 |
504 | Gateway Timeout | 由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答 |
505 | HTTP Version Not Supported | 服务器不支持请求中所指明的HTTP版本 |
常用
- 200 OK
一切正常,对GET和POST请求的应答文档跟在后面。在GET请求中,响应将包含与请求的资源相对应的实体。在POST请求中,响应将包含描述或操作结果的实体
-
204 No Content
服务器成功处理了请求,没有返回任何内容。没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。
-
301 Moved Permanently
客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL
-
302 Found
类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。注意,在HTTP1.0中对应的状态信息是“Moved Temporatily”。出现该状态代码时,浏览器能够自动访问新的URL,因此它是一个很有用的状态代码。注意这个状态代码有时候可以和301替换使用。例如,如果浏览器错误地请求
http://host/~user
(缺少了后面的斜杠),有的服务器 返回301,有的则返回302。严格地说,我们只能假定只有当原来的请求是GET时浏览器才会自动重定向。请参见307。 -
304 Not Modified
客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告 诉客户,原来缓冲的文档还可以继续使用
-
400 Bad Request
请求出现语法错误
-
401 Unauthorized
客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填 写合适的Authorization头后再次发出请求
-
403 Forbidden
资源不可用。服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致
-
404 Not Found
无法找到指定位置的资源
-
500 Internal Server Error
服务器遇到了意料不到的情况,不能完成客户的请求
-
503 Service Unavailable
服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个 Retry-After头
以上是我学习查阅资料所得,难免有错漏,望请海涵。
若需详细准确还请多方查阅。