http协议学习

http协议学习

学习主要内容,http的基本流程,缓存的是如何实现的,缓存的策略是怎么样的?

http web工作原理

  • 当输入url回车后,客户端(浏览器)会去请求DNS服务器
  • 通过DNS获取域名对应的IP地址
  • 通过IP这个地址找到对应的服务器,客户端通过TCP/IP协议与服务器端建立TCP连接
  • 建立连接后,客户端发送httpRequest(请求包)
  • 服务器接收并开始处理请求,调用自身服务,返回httpResponse(响应包)
  • 客户端收到响应包后,客户端与服务器端断开TCP连接,等待下一次请求

DNS

DNS:域名系统的缩写。它是用于TCP/IP网络,从事将主机名或者域名翻译成IP地址的工作。

DNS的工作流程:

  • 当输入网址后,操作系统先检查本地hosts文件,看看是否有这个网址的映射关系。
  • 第一步没有映射关系,查找本地DNS缓存,有则返回,完成域名解析。
  • 第一二步没有映射关系,则查找TCP/IP协议首选的DNS服务器(本地DNS服务器),有则返回给客户端,完成域名解析。
  • 上面几步都失效的情况下,则根据本地DNS服务器的设置查询,一级一级的查询上层DNS服务器,最后将结果返回给本地服务器,本地服务器再返回给客户端。

请求和相应

  • http请求由三部分组成,分别是:请求行、消息报头、请求正文
1
2
3
4
5
6
7
8
GET /domains/example/ HTTP/1.1      //请求行: 请求方法 请求URI HTTP协议/协议版本
Host:www.iana.org //服务端的主机名
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 //告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 //客户端能接收的mine
Accept-Encoding:gzip,deflate,sdch //是否支持流压缩
Accept-Charset:UTF-8,*;q=0.5 //客户端字符编码集
//空行
//消息体,请求资源参数,例如POST传递的参数
  • HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文
1
2
3
4
5
6
7
8
9
HTTP/1.1 200 OK                     //状态行:HTTP协议版本号 状态码 状态消息
Server: nginx/1.0.8 //服务器使用的WEB软件名及版本
Date:Date: Tue, 30 Oct 2012 04:14:25 GMT //发送时间
Content-Type: text/html //服务器发送信息的类型
Transfer-Encoding: chunked //表示发送HTTP包是分段发的
Connection: keep-alive //保持连接状态
Content-Length: 90 //主体内容长度
//空行
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... //消息体

Connection:keep-alive
从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接.
Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同服务器软件(如Apache)中设置这个时间。

状态码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1XX 提示信息 - 表示请求已被成功接收,继续处理 
2XX 成功 - 表示请求已被成功接收,理解,接受
3XX 重定向 - 要完成请求必须进行更进一步的处理
4XX 客户端错误 - 请求有语法错误或请求无法实现
5XX 服务器端错误 - 服务器未能实现合法的请求

常见状态代码:
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后,可能恢复正常

Http协议的cookie

  • Session和cookie的区别?
  • Session和cookie在返回客户端的时候在 Response Header 的setCookie字段中
  • 通过是否含有Express(有效期)字段来判断
  • 有Express的Cookie就是普通的Cookie,没有Express可能是Session 或 临时的Cookie,Session就是临时的Cookie
  • Cookie的字段:domain path name value express comment commenturl httpon httponly 等

Http协议的缓存

  • HTTP协议分别在 1.0 / 1.1 两个时代推出了 Expires / Cache-control 两种cache策略

Cache策略(1.1的版本)

1.保鲜期

只需要在响应头中设定:
Cache-control: max-age=[secs]
[secs]是cache在客户端存活的秒数
例如 Cache-control: max-age=1800 表明cache的时间是半小时,只使用这样一个声明就可以使浏览器能够将这个HTTP响应的内容写入临时目录做cache.

简要步骤

5分钟内

  • 浏览器再次请求 http://example.com/test.list
  • 查询临时文件目录发现存在cache存储,检查保鲜期max-age,发现还未过期,则直接读取之,响应给用户

5分钟后

  • 浏览器再次请求 http://example.com/test.list
  • 查询临时文件目录发现存在cache存储,检查保鲜期max-age,已经过期,则重新请求web server

2.保鲜期 + 最后修改时间验证

在给出保鲜期的同时,给出一个资源的验证方式:
Last-Modified: [UTC time]
[UTC time]标示这个响应资源的最后修改时间,例如 Last-Modified: Mon, 06 Jul 2016 09:21:48 GMT
这个响应头只有配合Cache-control的时候才有实际价值,只是声明校验资源的方式,并不能影响资源的保鲜期时长

利用资源的可校验性,我们可以实现在cache的资源超过保鲜期浏览器再次请求时的304响应,令浏览器再次使用之前的cache

简要步骤

5分钟内

  • 浏览器再次请求 http://example.com/test.list
  • 查询临时文件目录发现存在cache存储,检查保鲜期max-age,发现还未过期,则直接读取之,响应给用户

5分钟后

  • 浏览器再次请求 http://example.com/test.list
  • 查询临时文件目录发现存在cache存储,检查保鲜期max-age,已经过期发现资源具有Last-Modified声明,则为request header带上 If-Modified-Since: Mon, 06 Jul 2016 09:21:48 GMT 发送请求到web server
  • web server收到请求后发现有头If-Modified-Since则与被请求资源的最后修改时间进行比对,若最后修改时间较新,说明资源又被改动过,则响应整片资源内容,HTTP 200 (需要整块内容写为包体).若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体),告知浏览器继续使用所保存的cache,(这里当然也可以根据自己的需要决定是200还是304,我们的CGI毕竟是一种原始的实现)

3.保鲜期 + 自定义标识验证
在给出保鲜期的同时,给出另一种资源的验证方式:
ETag: [custom flag]
[custom flag]标示这个响应资源的由开发者自己确定的签名验证标识,例如 ETag: “abcdefg”,这个响应头只有配合Cache-control的时候才有实际价值,是声明校验资源的方式

ETag的使用为我们实现304响应提供了更多的灵活性,我们可以抛开必须将验证转化成时间格式的限制

简要步骤

5分钟内

  • 浏览器再次请求 http://example.com/test.list
  • 查询临时文件目录发现存在cache存储,检查保鲜期max-age,发现还未过期,则直接读取之,响应给用户

5分钟后

  • 浏览器再次请求 http://example.com/test.list
  • 查询临时文件目录发现存在cache存储,检查保鲜期max-age,已经过期发现资源具有ETag声明,则为请求带上头 If-None-Match: “abcdefg”,发送请求到web server
  • web server收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,Etag可以是一个版本号,可以是短时间戳,可以是资源校验和(强烈不推荐使用),或者干脆是一个常量(可以干脆拿来做容错)
    If-None-Match发来的串与我们的自有值比对,根据我们自己的任何策略算法,可以自由决定如何返回浏览器,304或200

  • 这里有一个使用ETag来做容错的例子:
    (1) 我们的每次正常返回都是200
    Cache-control: max-age=1800
    ETag: “anything” 这里anything是个常量,我们只用来告诉浏览器,cache过期要发带If-None-Match的请求过来
    (2)这样来自客户端的一大部分请求基本上都会带上If-None-Match头,我们的CGI据此可以知道这个请求的客户端是否有cache,此时如果 CGI联系server失败,那么可以直接返回304,驱使客户端使用上一次cache的正确结果,且更新保鲜期max-age为300秒,这样我们实现 了一个基于HTTP cache的容错,如果我们的资源还能实现一套时间戳存储的话,那么我们可以在正常情况下也实现校验后的304,从而节省流量

  • IE6 在资源有gzip压缩同时有ETag头时,cache后再次发请求不会带If-None-Match头!!!

参考