输入facebook的URL按下回车后究竟发生了什么

原创
网络
作为一名软件开发或是网络技术人员,你应该对Web应用程序的运行原理和协议交换,以及涉及到的技术:如浏览器、HTTP、HTML、Web服务器和请求处理程序等都有所了解才行。在这篇文章中,我们将深入探讨你访问某个URL时发生的一系列事情。

【51CTO.com 独家译稿】作为一名软件开发或是网络技术人员,你应该对Web应用程序的运行原理和协议交换,以及涉及到的技术:如浏览器、HTTP、HTML、Web服务器和请求处理程序等都有所了解才行。在这篇文章中,我们将深入探讨你访问某个URL时发生的一系列事情。

1、你在浏览器中输入某个URL

我们从这里开始:

图 1

图 1

2、浏览器查找该域名对应的IP地址

图 2

图 2

第一步是找出所访问域名对应的IP地址,按以下顺序循环查找DNS记录:

◆浏览器缓存 - 浏览器会缓存DNS记录一段时间,有趣的是,操作系统不会告诉浏览器每条DNS记录的存活时间,浏览器按照固定的周期进行缓存(每种浏览器的保留时间从2-30分钟长度不定)。

◆操作系统缓存 - 如果浏览器缓存中没有要找的记录,浏览器会产生一个系统调用(在Windows中是gethostbyname),操作系统有它自己的缓存。

◆路由器缓存 - 请求继续来到你的路由器,路由器通常也有自己的DNS缓存。

◆ISP DNS缓存 - 下一步要检查的是ISP的DNS服务器,当然也是有缓存的。

◆递归查找 - ISP的DNS服务器开始一个递归查找,从根域服务器开始,到.com顶级域名服务器,再到Facebook的域名服务器,正常情况下,DNS服务器将会缓存.com域名服务器的名字,因此不一定需要访问根域服务器。

下面是一个递归DNS查找过程示意图:

图 3

图 3

关于DNS一个令人担心的问题是,整个域名如wikipedia.org或facebook.com只映射到单个IP地址,幸运的是,有许多方法来消除这个问题。

◆循环DNS :DNS查找返回多个IP地址,例如,facebook.com真实情况是映射到了4个IP地址。

◆负载均衡: 由专用硬件监听一个特定IP地址,然后将请求转发给其它服务器,大型网站一般都使用了昂贵的高性能负载均衡设备。

◆基于地理位置的DNS: 将域名映射到不同地理位置的IP地址提高扩展性,对于托管静态内容的服务器布局来说,这个方法很有用,不同服务器之间不需要相互同步状态。

◆Anycast(任播): 它是一种路由技术,单个IP地址可以映射到多台物理服务器,遗憾的是,任播对TCP不友好,在实际中很少使用。

大多数DNS服务器本身使用任播实现高可用和DNS查找的低延迟。

3、浏览器向Web服务器发送一个HTTP请求

图 4

图 4#p#

Facebook的主页是不会直接从浏览器缓存提取的,因为动态页面要么很快(或立即)过期,因此浏览器将向Facebook服务器发送一条请求:

GET http://facebook.com/ HTTP/1.1
Accept: 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
Connection: Keep-Alive
Host: facebook.com
Cookie: datr=1265876274-[...]; locale=en_US; lsd=WW[...]; c_user=2101[...]

GET请求的URL是"http://facebook.com/",浏览器通过User-Agent消息头标识自己,并声明可接受的响应类型(Accept和Accept-Encoding消息头),Connection消息头要求服务器保持TCP连接打开,以便处理下一步请求。

请求包含了浏览器对该域名的cookie,你可能已经知道,cookie是key-value成对出现的,它可以跟踪不同页面请求之间网站的状态,因此cookie保存了登录的用户名,服务器会给用户分配一段密码数字,cookie在客户端上实际是一个文本文件,它会跟随每个请求发给服务器。

有许多工具可以查看原始HTTP请求和对应的响应,我最喜欢的是fiddler,也许你想说的是FireBug,没错,工具很多,就看个人喜好了,这些工具都能帮助你优化网站。

除了GET请求外,你可能还熟悉另一种类型的请求- POST请求,它通常用于提交表单,GET请求通过URL发送它的参数(如http://robozzle.com/puzzle.aspx?id=85),POST请求在请求主体中发送它的参数。

在URL"http://facebook.com/"中的斜线非常重要,在这里,浏览器可以安全地添加斜线,对于"http://example.com/folderOrFile"这种格式的URL,浏览器不能自动添加一个斜线,因为尚不清楚folderOrFile是一个文件夹还是一个文件,在这种情况下,浏览器不会擅自添加斜线,服务器将会以重定向作为响应,导致不必要的来回通信。

4、Facebook服务器以一个永久重定向响应

图 5

图 5

下面是Facebook服务器向浏览器请求发回的响应:

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: http://www.facebook.com/
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

服务器以301永久移走响应告诉浏览器应转到"http://www.facebook.com/"而不是"http://facebook.com/"。

你可能会问,为什么服务器要坚持用重定向进行响应呢?为什么不用用户想看的网页进行响应呢?

一个原因是搜索引擎排名,如果相同网页有两个URL,如http://www.igoro.com/http://igoro.com/,搜索引擎会将他俩看作是两个不同的网站,分摊到每个URL的入站连接就要少得多,从而降低了网站的排名,搜索引擎理解永久重定向(301),将会把来自这两个源的入站连接合并成一个排名。

同样,相同内容对应的URL太多也利于缓存,如果某段内容有多个名字,在缓存中可能也会出现多次。

5、浏览器跟随重定向

图 6

图 6

浏览器现在知道"http://www.facebook.com/"才是正确的URL,于是发出第二个GET请求。

GET http://www.facebook.com/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, [...]
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Cookie: lsd=XW[...]; c_user=21[...]; x-referer=[...]
Host: www.facebook.com

消息头和第一个请求的含义一样,就不再啰嗦了。#p#

6、服务器处理请求

图 7

图 7

服务器将会收到GET请求并进行处理,然后发回响应,看起来是一个非常简单的操作,但实际上在这个期间发生了许多有趣的事情。

◆Web服务器软件

Web服务器软件(如IIS或Apache)收到HTTP请求后,立即确定由哪个请求处理程序来处理这个请求,请求处理程序读取请求,生成HTML。

举一个最简单的例子,请求处理程序可以保存在一个文件中,其结构和URL结构完全对应,如http://example.com/folder1/page1.aspx URL映射到文件/httpdocs/folder1/page1.aspx,Web服务器软件也可以配置,将URL手工映射到请求处理程序,因此page1.aspx的公共URL应该是http://example.com/folder1/page1

◆请求处理程序

请求处理程序读取请求,它的参数和cookie,它可能会读取和更新服务器上的某些数据,然后生成一个HTML页面作为响应。

每个动态网站面临的一个有趣的困难是如何保存数据,小网站通常只有一个SQL数据库来保存数据,但大型网站必须将数据库部署到多台服务器上,解决办法包括水平分区(根据主键,将一张表拆分到多个数据库),复制和使用简化数据库(不追求一致性)。

保持数据廉价更新的一个技术是使用批处理作业,例如,Facebook会及时更新新闻消息源,但"你可能知道"功能可能只需要每晚进行更新(我猜的,我也不知道真实情况如何),批处理作业更新会产生一些过时的不重要的数据,但它使数据更新更快,更简单。

7、服务器发回HTML响应

图 8

图 8

下面是服务器生成并发回的一个响应:

HTTP/1.1 200 OK
Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0,
    pre-check=0
Expires: Sat, 01 Jan 2000 00:00:00 GMT
P3P: CP="DSP LAW"
Pragma: no-cache
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
X-Cnection: close
Transfer-Encoding: chunked
Date: Fri, 12 Feb 2010 09:05:55 GMT

2b3????????T?n?@????[...]
The entire response is 36 kB, the bulk of them in the byte blob at the end that I trimmed.
The Content-Encoding header tells the browser that the response body is compressed using the gzip algorithm.

After decompressing the blob, you'll see the HTML you'd expect:
<!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-Typt设置成text/html了,它告诉浏览器以HTML呈现响应的内容,而不是作为一个文件下载,浏览器通过消息头决定如何解释响应的内容,但也会考虑其他因素,如URL扩展。

8、浏览器开始渲染HTML

在浏览器未接收完整个HTML文档之前,它就开始渲染了。

图 9

图 9

9、浏览器发送嵌入到HTML中的对象请求

图 10

图 10#p#

在浏览器渲染HTML时,它会发现还需要访问其它URL,浏览器继续为这些资源发出GET请求,下面是我访问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

每个URL都会经历访问HTML页面类似的过程,因此,浏览器会在DNS中查找域名,发送请求,跟随重定向等。

但静态文件 - 和动态页面不一样 - 允许浏览器缓存,有些文件在下一次访问时可直接从浏览器缓存中提取,不用联系服务器,浏览器知道某个特定文件的缓存有效期,因为第一次从服务器返回到浏览器时就包含了Expires头信息,此外,每个响应可能也包含一个类似版本号的ETag头,如果浏览器看到一个ETag,它会立即停止传输文件。

你能猜到URL中的fbcdn.net代表什么吗?没错,它表示Facebook内容交付网络,Facebook使用内容交付网络(CDN)分发静态内容 - 图像,样式表和JavaScript文件,因此,文件将被复制到全球许多服务器上。

静态内容通常会占用网站的大量带宽,但也很容易被复制到CDN网络中的加速节点,一般情况下,网站会使用第三方CDN提供商,而不是自己运营CDN,例如,Facebook的静态文件由世界最大的CDN提供商Akamai托管。

我们还是举一个例子,当你ping static.ak.fbcdn.net时,你会从akamai.net服务器得到一个应答,同样,如果你分多次ping URL,可能会从不同的服务器得到应答,这说明背后的负载均衡正在发生作用。

10、浏览器进一步发送异步(Ajax)请求

图 11

图 11

根据Web 2.0的精神,即使页面渲染完毕后,客户端也要继续和服务器通信。

例如,Facebook chat会持续更新你的朋友列表(他们登录和退出都会很快反馈给你),在你浏览器中执行的JavaScript向服务器发送一个异步请求,异步请求是通过编程实现的指向特定URL的GET或POST请求,还是以Facebook为例,客户端向http://www.facebook.com/ajax/chat/buddy_list.php发送一个POST请求,获取你的在线朋友列表。

这种模式有时指的是Ajax,Ajax表示异步JavaScript和XML,但服务器不一定非要以XML格式进行响应,例如,Facebook返回JavaScript代码片段响应异步请求。

Fiddler工具允许你查看浏览器发送的异步请求,实际上,你不但可以观察请求,而且还可以修改这些请求并进行重发,因此可以轻松欺骗Ajax请求,许多在线游戏的开发人员也因此而郁闷不已。

Facebook chat提供了一个有趣的Ajax问题示例:将数据从服务器推向客户端。因为HTTP是一个请求-响应协议,聊天服务器不能将新消息推送给客户端,相反,客户端必须每隔几秒从服务器去取数据,以了解是否有新消息到达。

长轮询在这种情景中对降低服务器负载很有用,轮询时如果服务器没有任何新消息,它就不发回应答,同时,如果该客户端有新消息到达,服务器会发现未完成的请求,并返回消息作为响应。

原文出处:http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url/

原文名:What really happens when you navigate to a URL

作者:Igor Ostrovsky

【51CTO.com独家译稿,非经授权谢绝转载!合作媒体转载请注明原文出处及出处!】

责任编辑:佟健 来源: 51CTO.com
相关推荐

2021-05-27 10:26:00

地址栏URLhttp

2020-09-01 11:40:01

HTTPJavaTCP

2020-10-09 08:59:55

输入网址解密

2024-05-06 10:53:22

浏览器TCPHTTPS

2023-01-14 16:11:27

浏览器URL回车

2024-04-11 08:33:25

2020-11-06 15:20:45

浏览器前端架构

2021-02-25 10:02:32

开机键Linux内存

2020-05-15 14:30:23

前端浏览器架构

2022-06-03 08:12:52

InnoDB插入MySQL

2017-04-11 13:54:49

HTTPURLHTML

2022-04-28 07:52:05

HTTP浏览器

2019-08-26 09:35:25

命令ping抓包

2018-03-16 15:31:50

2021-01-21 14:09:28

云计算华为云

2021-12-16 15:58:48

Linux内存微软

2023-12-12 17:56:05

终端JavaScrip代码

2021-04-20 19:15:51

浏览器网络URL

2022-05-26 23:36:36

SQLMySQL数据

2023-11-02 08:00:00

ClickHouse数据库
点赞
收藏

51CTO技术栈公众号