HTTP 无状态性
HTTP 协议是无状态的 (stateless) 也就是说, 同一个客户端第二次访问同一个服务器上的页面时, 服务器无法知道这个客户端曾经访问过, 服务器也无法分辨不同的客户端 HTTP 的无状态特性简化了服务器的设计, 使服务器更容易支持大量并发的 HTTP 请求
HTTP 持久连接
HTTP1.0 使用的是非持久连接, 主要缺点是客户端必须为每一个待请求的对象建立并维护一个新的连接, 即每请求一个文档就要有两倍 RTT 的开销因为同一个页面可能存在多个对象, 所以非持久连接可能使一个页面的下载变得十分缓慢, 而且这种短连接增加了网络传输的负担 HTTP1.1 使用持久连接 keepalive, 所谓持久连接, 就是服务器在发送响应后仍然在一段时间内保持这条连接, 允许在同一个连接中存在多次数据请求和响应, 即在持久连接情况下, 服务器在发送完响应后并不关闭 TCP 连接, 而客户端可以通过这个连接继续请求其他对象
HTTP/1.1 协议的持久连接有两种方式:
非流水线方式: 客户在收到前一个响应后才能发出下一个请求;
流水线方式: 客户在收到 HTTP 的响应报文之前就能接着发送新的请求报文;
1 首先, 在浏览器里输入网址:
技术分享
2 浏览器根据域名解析 IP 地址:
技术分享
浏览器根据访问的域名找到其 IP 地址 DNS 查找过程如下:
1)浏览器缓存: 浏览器会缓存 DNS 记录一段时间 但操作系统没有告诉浏览器储存 DNS 记录的时间, 这样不同浏览器会储存个自固定的一个时间(2 分钟到 30 分钟不等)
2)系统缓存: 如果在浏览器缓存里没有找到需要的域名, 浏览器会做一个系统调用(windows 里是 gethostbyname), 这样便可获得系统缓存中的记录
3)路由器缓存: 如果系统缓存也没找到需要的域名, 则会向路由器发送查询请求, 它一般会有自己的 DNS 缓存
4)ISP DNS 缓存: 如果依然没找到需要的域名, 则最后要查的就是 ISP 缓存 DNS 的服务器在这里一般都能找到相应的缓存记录
域名解析原理:
1 > 一个域中的每个主机名与其 IP 地址的映射关系由这个域的 DNS 服务器负责管理, 例如,"www.it.orgftp.it.orgblog.it.org 等主机名都由管理域 it.org 的 DNS 服务器进行管理, 而不能由管理域 org 的 DNS 服务器进行管理
2 > 每个管理域都必须在其直接父域的 DNS 服务器上注册该子域的名称和该子域的 DNS 服务器的 IP 地址, 例如, 必须在管理域 org 的 DNS 服务器注册子域 it.org 和其 DNS 服务器的 IP 地址后, 域名 it.org 才能真正被外界所认可
3 > 为了方便对顶级域名的统一管理, 在顶级域名之上其实还有一个根域名, 根域名用点 (.) 表示, 例如, www.it.org 也可以写为 www.it.org.,www.it.org. 中的最后的那个点 (.) 就表示根域名 Internet 中的根域名由 InterNIC(国际互联网络信息中心)集中管理, 顶级域名和其下的域名则由拥有该域名的组织公司和个人自己管理
域名解析的方式主要有两种, 分别是:
技术分享
或者
技术分享
DNS 有一个弊端, 一个域名看上去只是对应一个单独的 IP 地址还好有几种方法可以消除这个瓶颈:
1 > 循环 DNS 是 DNS 查找时返回多个 IP 时的解决方案举例来说, facebook.com 实际上就对应了四个 IP 地址
2 > 负载平衡器是以一个特定 IP 地址进行侦听并将网络请求转发到集群服务器上的硬件设备 一些大型的站点一般都会使用这种昂贵的高性能负载平衡器
3 > 地理 DNS 根据用户所处的地理位置, 通过把域名映射到多个不同的 IP 地址提高可扩展性这样不同的服务器不能够更新同步状态, 但映射静态内容的话非常好
4>Anycast 是一个 IP 地址映射多个物理主机的路由技术 美中不足的是 Anycast 与 TCP 协议适应的不是很好, 所以很少应用在那些方案中大多数 DNS 服务器使用 Anycast 来获得高效低延迟的 DNS 查找
3 浏览器与 web 服务器建立一个 TCP 连接
4 浏览器给 Web 服务器发送一个 http 请求:
技术分享
一个 http 请求报文由请求行 < request-line > 请求头部 < headers > 空行<blank-line>
和请求数据<request-body>4 个部分组成, 请求报文的一般格式如下图:
技术分享
1)请求行: 由请求方法 URL 和 HTTP 协议版本 3 个字段组成, 它们用空格分隔例如, GET /index.html HTTP/1.1HTTP 协议的请求方法有 GETPOSTHEADPUTDELETEOPTIONSTRACECONNECT 而常见的有如下几种:
1>GET: 当客户端要从服务器中读取文档时, 当点击网页上的链接或者通过在浏览器的地址栏输入网址来浏览网页的, 使用的都是 GET 方式 GET 方法要求服务器将 URL 定位的资源放在响应报文的数据部分, 回送给客户端使用 GET 方法时, 请求参数和对应的值附加在 URL 后面, 利用一个问号 (?) 代表 URL 的结尾与请求参数的开始, 传递参数长度受限制例如,/index.jsp?id=100&op=bind 通过 GET 方式传递的数据直接放在在地址中, 所以 GET 方式的请求一般不包含请求内容部分, 请求数据以地址的形式表现在请求行地址中? 之后的部分就是通过 GET 发送的请求数据, 我们可以在地址栏中清楚的看到, 各个数据之间用 & 符号隔开显然这种方式不适合传送私密数据另外, 由于不同的浏览器对地址的字符限制也有所不同, 一般最多只能识别 1024 个字符, 所以如果需要传送大量数据的时候, 也不适合使用 GET 方式如果数据是英文字母 / 数字, 原样发送, 如果是空格, 转换为 +, 如果是中文 / 其他字符, 则直接把字符串用 BASE64 加密, 得出如: 你好, 其中%XX 中的 XX 为该符号以 16 进制表示的 ASCII
2>POST: 允许客户端给服务器提供信息较多 POST 方法将请求参数封装在 HTTP 请求数据中, 以名称 / 值的形式出现, 可以传输大量数据, 这样 POST 方式对传送的数据大小没有限制, 而且也不会显示在 URL 中 POST 方式请求行中不包含数据字符串, 这些数据保存在请求内容部分, 各数据之间也是使用 & 符号隔开 POST 方式大多用于页面的表单中因为 POST 也能完成 GET 的功能, 因此多数人在设计表单的时候一律都使用 POST 方式, 其实这是一个误区 GET 方式也有自己的特点和优势, 我们应该根据不同的情况来选择是使用 GET 还是使用 POST
3>HEAD: 就像 GET, 只不过服务端接受到 HEAD 请求后只返回响应头, 而不会发送响应内容当我们只需要查看某个页面的状态的时候, 使用 HEAD 是非常高效的, 因为在传输的过程中省去了页面内容
2)请求头部: 由关键字 / 值对组成, 每行一对, 关键字和值用英文冒号: 分隔请求头部通知服务器有关于客户端请求的信息, 典型的请求头有:
User-Agent: 产生请求的浏览器类型
Accept: 客户端可识别的内容类型列表星号 * 用于按范围将类型分组, 用 */* 指示可接受全部类型, 用 type/* 指示可接受 type 类型的所有子类型
Host: 要请求的主机名, 允许多个域名同处一个 IP 地址, 即虚拟主机
Accept-Language: 客户端可接受的自然语言
Accept-Encoding: 客户端可接受的编码压缩格式
Accept-Charset: 可接受的应答的字符集
connection: 连接方式(close 或 keepalive)
Cookie: 存储于客户端扩展字段, 向同一域名的服务端发送属于该域的 cookie
3)空行: 最后一个请求头部之后是一个空行, 发送回车符和换行符, 通知服务器以下不再有请求头部
4)请求数据: 请求数据不在 GET 方法中使用, 而在 POST 方法中使用 POST 方法适用于需要客户填写表单的场合与请求数据相关的最常使用的请求头部是 Content-Type 和 Content-Length
请求报文示例:
- POST /search HTTP/1.1
- Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,
- application/msword, application/x-silverlight, application/x-shockwave-flash, /
- Referer: <a href="http://www.google.cn/">http://www.google.cn/</a>;
- Accept-Language: zh-cn
- Accept-Encoding: gzip, deflate
- User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)
- Host: <a href="http://www.google.cn">www.google.cn</a>;
- Connection: Keep-Alive
- Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
- NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
- FxlRugatx63JLv7CWMD6UB_O_r
- hl=zh-CN&source=hp&q=domety
5 服务器的永久重定向响应:
技术分享
服务器给浏览器响应一个 301 永久重定向响应, 这样浏览器就会访问 http://www.facebook.com/ 而非 http://facebook.com / 为什么服务器一定要重定向而不是直接发送用户想看的网页内容呢? 其中一个原因跟搜索引擎排名有关如果一个页面有两个地址, 就像 http://www.igoro.com / 和 http://igoro.com/, 搜索引擎会认为它们是两个网站, 结果造成每个搜索链接都减少从而降低排名而搜索引擎知道 301 永久重定向是什么意思, 这样就会把访问带 www 的和不带 www 的地址归到同一个网站排名下还有就是用不同的地址会造成缓存友好性变差, 当一个页面有好几个名字时, 它可能会在缓存里出现好几次
一个 http 响应报文由状态行 < status-line > 响应头部 < headers > 空行<blank-line>
和响应数据<response-body>4 个部分组成, 响应报文的一般格式如下图:
技术分享
1)状态行: 由 HTTP 协议版本服务器返回的响应状态码和响应状态码的文本描述组成
状态代码由三位数字组成, 第一个数字定义了响应的类别, 且有五种可能取值
1xx: 信息性状态码, 表示服务器已接收了客户端请求, 客户端可继续发送请求
- Continue
- Switching Protocols
2xx: 成功状态码, 表示服务器已成功接收到请求并进行处理
200 OK 表示客户端请求成功
204 No Content 成功, 但不返回任何实体的主体部分
206 Partial Content 成功执行了一个范围 (Range) 请求
3xx: 重定向状态码, 表示服务器要求客户端重定向
301 Moved Permanently 永久性重定向, 响应报文的 Location 首部应该有该资源的新 URL
302 Found 临时性重定向, 响应报文的 Location 首部给出的 URL 用来临时定位资源
303 See Other 请求的资源存在着另一个 URI, 客户端应使用 GET 方法定向获取请求的资源
304 Not Modified 客户端发送附带条件的请求 (请求首部中包含如 If-Modified-Since 等指定首部) 时, 服务端有可能返回 304, 此时, 响应报文中不包含任何报文主体
307 Temporary Redirect 临时重定向与 302 Found 含义一样 302 禁止 POST 变换为 GET, 但实际使用时并不一定, 307 则更多浏览器可能会遵循这一标准, 但也依赖于浏览器具体实现
4xx: 客户端错误状态码, 表示客户端的请求有非法内容
400 Bad Request 表示客户端请求有语法错误, 不能被服务器所理解
401 Unauthonzed 表示请求未经授权, 该状态代码必须与 WWW-Authenticate 报头域一起使用
403 Forbidden 表示服务器收到请求, 但是拒绝提供服务, 通常会在响应正文中给出不提供服务的原因
404 Not Found 请求的资源不存在, 例如, 输入了错误的 URL
5xx: 服务器错误状态码, 表示服务器未能正常处理客户端的请求而出现意外错误
500 Internel Server Error 表示服务器发生不可预期的错误, 导致无法完成客户端的请求
503 Service Unavailable 表示服务器当前不能够处理客户端的请求, 在一段时间之后, 服务器可能会恢复正常
2)响应头部: 由关键字 / 值对组成, 每行一对, 关键字和值用英文冒号: 分隔, 典型的响应头有:
Location: 用于重定向接受者到一个新的位置例如: 客户端所请求的页面已不存在原先的位置, 为了让客户端重定向到这个页面新的位置, 服务器端可以发回 Location 响应报头后使用重定向语句, 让客户端去访问新的域名所对应的服务器上的资源
Server: 包含了服务器用来处理请求的软件信息及其版本它和 User-Agent 请求报头域是相对应的, 前者发送服务器端软件的信息, 后者发送客户端软件 (浏览器) 和操作系统的信息
Vary: 指示不可缓存的请求头列表
Connection: 连接方式
对于请求来说: close(告诉 WEB 服务器或者代理服务器, 在完成本次请求的响应后, 断开连接, 不等待本次连接的后续请求了)keepalive(告诉 WEB 服务器或者代理服务器, 在完成本次请求的响应后, 保持连接, 等待本次连接的后续请求);
对于响应来说: close(连接已经关闭); keepalive(连接保持着, 在等待本次连接的后续请求); Keep-Alive: 如果浏览器请求保持连接, 则该头部表明希望 WEB 服务器保持连接多长时间(秒); 例如: Keep-Alive:300;
WWW-Authenticate: 必须被包含在 401 (未授权的)响应消息中, 这个报头域和前面讲到的 Authorization 请求报头域是相关的, 当客户端收到 401 响应消息, 就要决定是否请求服务器对其进行验证如果要求服务器对其进行验证, 就可以发送一个包含了 Authorization 报头域的请求
)空行: 最后一个响应头部之后是一个空行, 发送回车符和换行符, 通知浏览器以下不再有响应头部
)响应数据: 服务器返回给客户端的文本信息
响应报文示例:
- HTTP / 1.1 301 Moved Permanently Cache - Control: private,
- no - store,
- no - cache,
- must - revalidate,
- post - check = 0,
- pre - check = 0 Expires: Sat,
- 01 Jan 2000 00 : 00 : 00 GMT Location: <a target = _blank href = "http://www.facebook.com/" > HTTP: //www.facebook.com/</a>;
- P3P: CP = DSP LAW Pragma: no - cache Set - Cookie: made_write_conn = deleted;
- expires = Thu,
- 12 - Feb - 2009 05 : 09 : 50 GMT;
- path = /; domain=.facebook.com; httponly
- Content-Type: text/html;
- charset = utf - 8 X - Cnection: close Date: Fri,
- 12 Feb 2010 05 : 09 : 51 GMT Content - Length: 0
6 浏览器跟踪重定向地址:
技术分享
现在浏览器知道了 HTTP://www.facebook.com / 才是要访问的正确地址, 所以它会发送另一个 http 请求
7 服务器处理请求:
服务器接收到获取请求, 然后处理并返回一个响应这表面上看起来是一个顺向的任务, 但其实这中间发生了很多有意思的东西, 就像作者博客这样简单的网站, 何况像 facebook 那样访问量大的网站呢! web 服务器软件 (像 IIS 和阿帕奇) 接收到 HTTP 请求, 然后确定执行某一请求处理来处理它请求处理就是一个能够读懂请求并且能生成 HTML 来进行响应的程序(像 ASP.NET,PHP,RUBY)
8 服务器发回一个 HTML 响应
9 释放 TCP 连接
若 connection 模式为 close, 则服务器主动关闭 TCP 连接, 客户端被动关闭连接, 释放 TCP 连接; 若 connection 模式为 keepalive, 则该连接会保持一段时间, 在该时间内可以继续接收请求;
10 客户端浏览器解析 HTML 内容
客户端将服务器响应的 html 文本解析并显示
11 浏览器获取嵌入在 HTML 中的对象
在浏览器显示 HTML 时, 它会注意到需要获取其他地址内容的标签这时浏览器会发送一个获取请求来重新获得这些文件这些地址都要经历一个和 HTML 读取类似的过程所以浏览器会在 DNS 中查找这些域名, 发送请求, 重定向等等
参考: http://blog.csdn.net/saiwaifeike/article/details/8789624
[http://blog.csdn.net/zhangliang_571/article/details/23508953](http://blog.csdn.net/zhangliang_571/article/details/23508953)
来源: http://www.qdfuns.com/article/46360/cb69a960f103d509a6f48fa485293569.html