在浏览器输入一个地址的过程

1.在浏览器中输入URL

这一切都从这里开始:

在浏览器输入一个地址的过程

2.浏览器查找域名的IP地址

 在浏览器输入一个地址的过程

导航的第一步是找出访问域的IP地址。DNS查找进行如下:

  • 浏览器缓存 -浏览器缓存DNS记录一段时间。有趣的是,操作系统并没有告诉浏览器每个DNS记录的生存时间,因此浏览器会将其缓存一段固定的时间(浏览器间隔2到30分钟)。
  • 操作系统缓存 - 如果浏览器缓存不包含所需的记录,则浏览器进行系统调用(Windows中的gethostbyname)。操作系统有自己的缓存。
  • 路由器缓存 - 请求继续到您的路由器,路由器通常具有自己的DNS缓存。
  • ISP DNS缓存 - 检查的下一个位置是缓存ISP的DNS服务器。有缓存,自然。
  • 递归搜索 - 您的ISP的DNS服务器开始递归搜索,从根名称服务器通过.com顶级名称服务器到Facebook的名称服务器。通常,DNS服务器将在缓存中具有.com名称服务器的名称,因此对根名称服务器的命中是不必要的。

以下是递归DNS搜索的示意图:

在浏览器输入一个地址的过程 

3.浏览器向Web服务器发送HTTP请求

在浏览器输入一个地址的过程

可以非常确定Facebook的主页将不会从浏览器缓存中提供,因为动态页面会非常快速或即时(过期日期设置为过期)。

因此,浏览器会将此请求发送到Facebook服务器:

GET http://facebook.com/ HTTP / 1.1
接受:application / x-ms-application,image / jpeg,application / xaml + xml,[...] 
User-Agent:Mozilla / 4.0(compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
Accept-Encoding:gzip,deflate
连接:保持活力
主持人:facebook.com
饼干:DATR = 1265876274- [...] ; 区域设置= EN_US; LSD = WW [...] ; c_user = 2101 [...]

GET请求命名要提取的URL  “http://facebook.com/”。浏览器识别自己(User-Agent头),并说明它将接受什么类型的响应(AcceptAccept-Encoding标头)。该连接头要求服务器以保持TCP连接开放的进一步请求。

该请求还包含浏览器对此域的Cookie。您可能已经知道,Cookie是跟踪不同页面请求之间的网站状态的键值对。因此,Cookie会存储登录用户的名称,由服务器分配给用户的密码,用户的某些设置等。Cookie将存储在客户端上的文本文件中,并发送到服务器与每个请求。

4.Facebook服务器以永久重定向方式进行响应

在浏览器输入一个地址的过程

这是Facebook服务器发送回浏览器请求的响应:

HTTP / 1.1 301永久移动
Cache-Control:private,no-store,no-cache,must-revalidate,post-check = 0,
      前检查= 0
过期日:2000年1月1日星期六00:00:00 GMT
位置:http://www.facebook.com/
P3P:CP =“DSP LAW”
Pragma:不缓存
Set-Cookie:made_write_conn = deleted; expires =星期四,2009年2月12日05:09:50 GMT;
      路径= /; 域= .facebook.com; 仅Http
内容类型:text / html; 字符集= utf-8的
X-Cnection:关闭
日期:2010年2月12日,星期五05:09:51 GMT
内容长度:0

服务器回复了301移动永久响应,告诉浏览器转到“http://www.facebook.com/”而不是“http://facebook.com/”。

有一些有趣的原因为什么服务器坚持重定向,而不是立即响应用户想要看到的网页。

一个原因与搜索引擎排名有关。请参阅如果同一页面有两个URL,例如http://www.igoro.com/http://igoro.com/,搜索引擎可能会认为它们是两个不同的网站,每个网站的入站链路较少,因此排名较低。搜索引擎了解永久重定向(301),并将来自两个来源的传入链接组合成单个排名。

此外,同一内容的多个URL不是缓存友好的。当一段内容有多个名称时,它会在缓存中潜在出现多次。

5.浏览器遵循重定向

在浏览器输入一个地址的过程

浏览器现在知道“http://www.facebook.com/”是正确的URL,因此它会发出另一个GET请求:

GET http://www.facebook.com/ HTTP / 1.1
接受:application / x-ms-application,image / jpeg,application / xaml + xml,[...]
接受语言:en-US
用户代理:Mozilla / 4.0(兼容; MSIE 8.0; Windows NT 6.1; WOW64; [...]
Accept-Encoding:gzip,deflate
连接:保持活力
Cookie:lsd = XW [...] ; c_user = 21 [...] ; x-referer = [...] 
主持人:www.facebook.com

标题的含义与第一个请求相同。

6.服务器‘处理‘请求

在浏览器输入一个地址的过程

服务器将收到GET请求,处理它并发送回应。

这似乎是一个简单的任务,但事实上,这里发生了很多有趣的事情 - 即使在像我的博客这样的简单网站上,更不用说像Facebook这样大规模扩展的网站。

  • Web服务器软件
    Web服务器软件(例如IIS或Apache)接收HTTP请求,并决定执行哪个请求处理程序来处理此请求。请求处理程序是一个读取请求并生成响应的HTML的程序(在ASP.NET,PHP,Ruby,...中)。

    在最简单的情况下,请求处理程序可以存储在结构反映URL结构的文件层次结构中,例如http://example.com/folder1/page1.aspx URL将映射到file / httpdocs / folder1 / page1的.aspx。也可以配置Web服务器软件,以便将URL手动映射到请求处理程序,因此page1.aspx的公共URL可以是http://example.com/folder1/page1

  • 请求处理程序
    请求处理程序读取请求,其参数和Cookie。它将读取并可能更新存储在服务器上的一些数据。然后,请求处理程序将生成一个HTML响应。

每个动态网站面临的一个有趣的难题是如何存储数据。较小的站点通常会有一个SQL数据库来存储他们的数据,但存储大量数据和/或有许多访问者的站点必须找到一种在多台机器上分割数据库的方式。解决方案包括分片(基于主键分割多个数据库的表),复制以及使用弱化一致性语义的简化数据库。

保持数据更新便宜的一种技术是将一些工作推迟到批处理作业。例如,Facebook必须及时更新新闻源,但支持“您可能认识的人”功能的数据可能只需要每晚更新(我的猜测,我实际上并不知道如何实现此功能)。批量作业更新导致一些不太重要的数据的陈旧,但可以使数据更新更快更简单。

7.服务器发回一个HTML响应

在浏览器输入一个地址的过程

以下是服务器生成并发回的响应:

HTTP / 1.1 200 OK
Cache-Control:private,no-store,no-cache,must-revalidate,post-check = 0,
    前检查= 0
过期日:2000年1月1日星期六00:00:00 GMT
P3P:CP =“DSP LAW”
Pragma:不缓存
内容编码:gzip
内容类型:text / html; 字符集= utf-8的
X-Cnection:关闭
转移编码:分块
日期:2010年2月12日,星期五09:05:55 GMT

2B3 Tn的@ [...]

整个响应是36 kB,大部分在我修剪结束的字节blob中。

内容编码头告诉该响应体用gzip算法压缩的浏览器。解压缩Blob后,您会看到您期望的HTML:

<!DOCTYPE html PUBLIC“ -  // W3C // DTD XHTML 1.0 Strict // EN”   
      “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html xmlns =“http://www.w3.org/1999/xhtml”xml:lang =“en” 
      lang =“en”id =“facebook”class =“no_js”>
<HEAD>
<meta http-equiv =“Content-type”content =“text / html; charset = utf-8”/>
<meta http-equiv =“Content-language”content =“en”/>
...

除了压缩,标题指定是否以及如何缓存页面,设置任何Cookie(在此响应中无),隐私信息等。

注意将Content-Type设置text / html的标题。标题指示浏览器将响应内容呈现为HTML,而不是将其作为文件下载。浏览器将使用标题来决定如何解释响应,但也会考虑其他因素,例如URL的扩展。

8.浏览器开始渲染HTML

即使在浏览器收到整个HTML文档之前,它也开始渲染网站:

 在浏览器输入一个地址的过程

9.浏览器发送嵌入HTML的对象的请求

在浏览器输入一个地址的过程

当浏览器呈现HTML时,它会注意到需要提取其他URL的标签。浏览器将发送GET请求以检索这些文件。

以下是我访问facebook.com的几个网址:

  • 图片
    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 
    ...

这些URL中的每一个将通过与HTML页面通过的过程类似的过程。因此,浏览器将在DNS中查找域名,向URL发送请求,重定向等。

但是,静态文件(与动态页面不同)允许浏览器缓存它们。一些文件可以从缓存中提供,而不需要联系服务器。浏览器知道缓存特定文件多长时间,因为返回文件的响应包含一个Expires头。此外,每个响应还可以包含一个类似版本号的ETag标头 - 如果浏览器看到已经具有的文件版本的ETag,则可以立即停止传输。

你可以猜测网址中的“fbcdn.net”代表什么?值得一提的是,这意味着“Facebook内容传送网络”。Facebook使用内容传送网络(CDN)来分发静态内容 - 图像,样式表和JavaScript文件。因此,这些文件将被复制到全球许多机器。

静态内容通常代表站点的大部分带宽,并且可以轻松地复制到CDN上。通常,网站将使用第三方CDN提供商,而不是自己运行CND。例如,Facebook的静态文件由最大的CDN提供商Akamai主办。

作为演示,当您尝试ping static.ak.fbcdn.net时,您将收到来自akamai.net服务器的响应。此外,有趣的是,如果您ping了URL几次,可能会收到来自不同服务器的响应,这表明后台发生的负载平衡。

10.浏览器发送进一步的异步(AJAX)请求

在浏览器输入一个地址的过程

以Web 2.0的精神,即使在页面呈现之后,客户端仍然继续与服务器进行通信。

例如,Facebook聊天将继续更新您登录的朋友的名单,因为他们来了。要更新已登录的朋友列表,浏览器中执行的JavaScript必须向服务器发送异步请求。异步请求是一种程序化构造的GET或POST请求,转到特殊的URL。在Facebook示例中,客户端向http://www.facebook.com/ajax/chat/buddy_list.php发送POST请求,以获取在线的朋友的列表。

这种模式有时被称为“AJAX”,它代表“异步JavaScript和XML”,尽管没有特别的理由为什么服务器必须将响应格式化为XML。例如,Facebook响应异步请求返回JavaScript代码片段。

除此之外,提示工具可让您查看浏览器发送的异步请求。实际上,你不仅可以被动地观察请求,还可以修改并重新发送。事实上,这是一个易于“欺骗”AJAX请求的事实,对于使用记分牌的在线游戏的开发者来说,造成了很大的伤害。(显然,请不要以这种方式作弊。)

Facebook聊天提供了一个AJAX有趣的问题的例子:将数据从服务器推送到客户端。由于HTTP是请求 - 响应协议,因此聊天服务器无法将新消息推送到客户端。相反,客户端必须每隔几秒轮询服务器,以查看是否有新消息到达。

长时间轮询是减少这些类型场景中服务器负载的有趣技术。如果服务器在轮询时没有任何新消息,则根本不会发回响应。而且,如果在超时期限内收到了一个此客户端的消息,服务器将发现未完成的请求并返回消息。