浏览器 http请求过程
1. 首先是输入网址
以www.facebook.com为例.
2. 浏览器查找域名对应IP
2.1 DNS查找过程:
- 浏览器缓存——浏览器会记录DNS一段时间(2-30分钟不等,视浏览器而定)
- 系统缓存——浏览器里没找到DNS缓存,此事浏览器做一个系统调用(window下是gethostbyname)。如发现匹配则采用。(与此对应有host恶意劫持更改攻击)
- 路由器缓存——路由器也会有DNS缓存(缓存你上过的网站,所以有时路由器需要进行DNS刷新)
- ISP DNS缓存——接下来是在ISP(互联网服务提供商)的DNS服务器的缓存上查找。**
- 递归查找——DNS缓存里没有的话,ISP DNS服务器会先后从根域名服务器(root)、.com顶级域名服务器、Facebook域名服务器获取IP(一般缓存内都会有,所以这一步一般不会发生)
DNS递归查找如下图所示:
DNS有一点令人担忧,这就是像wikipedia.org 或者 facebook.com这样的整个域名看上去只是对应一个单独的IP地址。还好,有几种方法可以消除这个瓶颈:
2.2 多IP域名DNS查询解决方案
- 循环DNS——单个域名、多个IP列表循环应对DNS查询
- 负载均衡器——一个特定IP的负载均衡服务器(例如:反向代理服务器)负责监听请求并转发给后面的多个服务器集群的某一个,实现多个服务器负载均衡
- 地理DNS——根据用户所处地理位置,返回不同的IP(应用:CDN)
- anycast——一个IP地址映射多个物理主机的路由技术
大多数DNS服务器使用Anycast来获得高效低延迟的DNS查找。
3. 发送请求
得到域名对应的IP后,就开始发送HTTP(S)请求了.
浏览器将把请求发送到Facebook所在的服务器, 请求头详解:
|
|
请求告诉服务器:
- 我要获取(GET) http://facebook.com/(GET的URL)这个页面
- Accept:我能接受这些类型的文件
- 我使用的是何种操作系统上的哪个类型那个版本的浏览器
- 接受何种方式的压缩文件
- 连接类型:短连接?长连接?
- 主机域名
- 发送存储在本机的cookies信息给服务器
除了获取请求,还有一种是发送请求,它常在提交表单用到。(如:搜索时要把搜索的内容一并发给服务器进行处理(在请求URL后面增加特定的用户参数),以获取特定的内容)
注意:URL后面加斜杠与不加斜杠的区别(文件夹与单个文件的区别)
http://www.facebook.com
http://www.facebook.com/
当我们输入http://www.facebook.com时,浏览器会自动添加斜杠,保证URL的严谨。
当我们输入:http://www.facebook.com/folderOrFile 时,因为浏览器不清楚folderOrFile到底是文件夹还是文件,所以不能自动添加 斜杠。这时,浏览器就不加斜杠直接访问地址,服务器会响应一个重定向,结果造成一次不必要的握手。
4. 重定向
当我们输入不完整的网址(http://facebook.com)时,或者网站迁移做了重定向设置时,服务器会进行一次重定向响应。
下面是重定向之后返回的响应头:
|
|
- 301 永久重定向
- 新的Location:……
为什么要重定向,而不直接返回用户想看的内容呢?(既然服务器已经经过重定向知道了用户需要什么)
答:原因之一:与搜索引擎排名有关。你看,如果一个页面有两个地址,就像http://www.igoro.com/ 和http://igoro.com/,搜索引擎会认为它们是两个网站,结果造成每一个的搜索链接都减少从而降低排名。而搜索引擎知道301永久重定向是 什么意思,这样就会把访问带www的和不带www的地址归到同一个网站排名下。还有一个是用不同的地址会造成缓存友好性变差。当一个页面有好几个名字时,它可能会在缓存里出现好几次。
5. 新的请求
重定向之后会发布一个新的获取请求
6. 服务器处理请求
6.1 web服务器软件
- 服务器操作系统种类:Linux(一般是厂家根据开源定制)、windows server系列(微软)
- 主要的服务器软件:IIS、Apache、Tomcat、JBOSS、Nginx、lighttpd、Tetty
- 服务器软件的作用:接收、处理与响应请求(了解CGI的作用)
6.2 处理流程:
- web服务器软件(如IIS或者Apache)接收到HTTP请求
- 确定执行那个请求处理程序(一个能读懂请求并且能生成HTML来进行响应的程序)(例如:java)来处理它
- 请求处理器阅读请求头的参数和cookies信息
- 更新服务器上的信息:例如更新数据库信息
- 生成HTML,压缩(gzip或其他),响应请求发送给用户
7. 服务器发回一个HTML响应
|
|
响应包括响应头(响应参数与信息)、响应body(主体文件)
响应包采用特定方法压缩,整个响应以blob类型传输,响应头指示响应包以何种方式压缩
这个响应头与重定向的响应头不太一样,这个响应头还包含着缓存选项,cookies设置和隐私信息等
注意: 报头中把Content-type设置为“text/html”。报头让浏览器将该响应内容以HTML形式呈现,而不是以文件形式下载它。浏览器会根据报头信息决定如何解释该响应,不过同时也会考虑像URL扩展内容等其他因素。
8. 浏览器开始显示HTML
浏览器在没有完整接收全部HTML文件,就已经开始显示页面了
9. 浏览器获取其他文件
浏览器解析HTML遇到需要下载的文件时,便再次向服务器(CDN)发送获取文件的请求。
下面是几个访问facebook.com时需要重获取的几个URL:
图片
http://static.ak.fbcdn.net/rsrc.php/z12E0/hash/8q2anwu7.gif
http://static.ak.fbcdn.net/rsrc.php/zBS5C/hash/7hwy7at6.gif
…
CSS 式样表
http://static.ak.fbcdn.net/rsrc.php/z448Z/hash/2plh8s4n.css
http://static.ak.fbcdn.net/rsrc.php/zANE1/hash/cvtutcee.css
…
JavaScript 文件
http://static.ak.fbcdn.net/rsrc.php/zEMOA/hash/c8yzb6ub.js
http://static.ak.fbcdn.net/rsrc.php/z6R9L/hash/cq2lgbs8.js
…
这些地址都要经历一个和HTML读取类似的过程。所以浏览器会在DNS中查找这些域名,发送请求,重定向等等…
但 不像动态页面那样,静态文件会允许浏览器对其进行缓存。有的文件可能会不需要与服务器通讯,而从缓存中直接读取。服务器的响应中包含了静态文件保存的期限 信息,所以浏览器知道要把它们缓存多长时间。还有,每个响应都可能包含像版本号一样工作的ETag头(被请求变量的实体值),如果浏览器观察到文件的版本 ETag信息已经存在,就马上停止这个文件的传输。
试着猜猜看“fbcdn.net”在地址中代表什么?聪明的答案是”Facebook内容分发网络”。Facebook利用内容分发网络(CDN)分发像图片,CSS表和JavaScript文件这些静态文件。所以,这些文件会在全球很多CDN的数据中心中留下备份。
静态内容往往代表站点的带宽大小,也能通过CDN轻松的复制。通常网站会使用第三方的CDN。例如,Facebook的静态文件由最大的CDN提供商Akamai来托管。
举例来讲,当你试着ping static.ak.fbcdn.net的时候,可能会从某个akamai.net服务器上获得响应。有意思的是,当你同样再ping一次的时候,响应的服务器可能就不一样,这说明幕后的负载平衡开始起作用了。
注意:
- 动态页面无法缓存,静态文件允许浏览器进行缓存。
- 静态文件本地有缓存时直接从本地读取
- 请求响应头内包含着静态文件保存的期限,浏览器知道下载的静态文件要静默保留多久。
- 响应头还会有静态文件的ETag(相当于版本号),当浏览器发现请求的静态文件的响应头的ETag与现有的缓存文件不符时,便会再次向服务器获取静态文件。
10. 浏览器发送异步(AJAX)请求
以 Facebook聊天功能为例,它会持续与服务器保持联系来及时更新你那些亮亮灰灰的好友状态。为了更新这些头像亮着的好友状态,在浏览器中执行的 JavaScript代码会给服务器发送异步请求。这个异步请求发送给特定的地址,它是一个按照程式构造的获取或发送请求。还是在Facebook这个例子中,客户端发送给http://www.facebook.com/ajax/chat/buddy_list.php一个发布请求来获取你好友里哪个在线的状态信息。
Facebook聊天功能提供了关于AJAX一个有意思的问题案例:把数据从服务器端推送到客户端。因为HTTP是一个请求-响应协议,所以聊天服务器不能把新消息发给客户。取而代之的是客户端不得不隔几秒就轮询下服务器端看自己有没有新消息。
这些情况发生时长轮询是个减轻服务器负载挺有趣的技术。如果当被轮询时服务器没有新消息,它就不理这个客户端。而当尚未超时的情况下收到了该客户的新消息,服务器就会找到未完成的请求,把新消息做为响应返回给客户端。
总结:
- web 2.0的一大特征就是页面显示完全后客户端仍旧与服务器端保持联系(keep-alive)
- 浏览器执行特定的JS代码会给服务器发送异步请求,获取最新的动态消息,使得页面能保持较新的状态。
- HTTP是一个请求-响应协议,只有在客户端发送请求,服务器端才能做出响应,而不能主动把消息或者文档发给客户
- 所以,要想保持页面处于最新的状态,需要定时进行轮询(定时发送AJAX请求以更新页面内容)
- AJAX请求十分容易更改,且用户十分容易自己制造和发送AJAX请求,所以没有验证码的没有IP限制条件的投票就是一个小游戏了(参照工作室两次刷票:自己定义IP,自己定时发送AJAX请求,然后票就哗哗的上了)。