精华内容
下载资源
问答
  • 浏览器输入一段URL后浏览器首先会对其进行解析,从而生成发送给 Web服务器的http请求消息。发送消息给WEB服务器的步骤需要操作系统来完成,浏览器本身并不具备将消息发送给服务器的功能。但是系统发送前必须要...

    1.生成Http请求

    1.1解析url生成请求

    在向浏览器输入一段URL后浏览器首先会对其进行解析,从而生成发送给 Web服务器的http请求消息。发送消息给WEB服务器的步骤需要操作系统来完成,浏览器本身并不具备将消息发送给服务器的功能。但是系统发送前必须要知道服务器的IP有了明确地址才能找到将要发送的目标。

    2.向DNS服务器查询IP

    首先我们知道url中输入的是域名,例如入www .baidu.com我们想要请求到其服务器必须知道它的IP地址。但是解析域名这个工作并不是浏览器帮我们做的,而是调用操作系统的域名解析器。你可以把它理解为就是DNS客户端,DNS解析器是包含在操作系统socket库中的一段程序。但是我们要知道DNS解析器并不具备直接像DNS服务器发送请求的能力。而是,需要委托给操作系统内部的协议栈来执行,解析器调用协议栈后,控制流程会再次转移,协议栈会执行发送消息的操作,然后通过网卡将消息发送给 DNS 服务器。当 DNS 服务器收到查询消息后,它会根据消息中的查询内容进行查询。客户端首先会采用UDP协议的方式访问最近的一台 DNS 服务器(也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)假设最近的 DNS 服务器中没有存放www .baid u.com 这一域名对应的信息,所以我们需要从顶层开始向下查找。最近的 DNS 服务器中保存了根域 DNS 服务器的信息,因此它会将来自客户端的查询消息转发给根域 DNS 服务器。根域服务器中也没有www .baidu.com 这个域名,但根据域名结构可以判断这个域名属于 com 域,因此根域 DNS 服务器会返回它所管理的 com 域中的DNS 服务器的 IP 地址,意思是“虽然我不知道你要查的那个域名的地址,但你可以去 com 域问问看”。接下来,最近的 DNS 服务器又会向 com 域的DNS 服务器发送查询消息。com 域中也没有www .baidu.com这个域名的信息,和刚才一样,com 域服务器会返回它下面的 baidu.com域的 DNS 服务器的 IP 地址。以此类推,只要重复前面的步骤,就可以顺藤摸瓜找到目标 DNS 服务器,只要向目标 DNS 服务器发送查询消息,就能够得到我们需要的答案,也就是 www .baidu.com 的 IP 地址了。收到客户端的查询消息之后,DNS 服务器会按照前面的方法来查询 IP地址,并返回给客户端。这样,客户端就知道了 Web 服务器的 IP 地址。上述过程只是一种很特殊的情况用来举例,实际中一个DNS服务器可以管理多个域的信息,上级域和下级域有可能共享同一台 DNS 服务器。在这种情况下,访问上级 DNS 服务器时就可以向下跳过一级 DNS 服务器,直接返回再下一级 DNS 服务器的相关信息。此外,有时候并不需要从最上级的根域开始查找,因为 DNS 服务器有一个缓存功能,可以记住之前查询过的域名。如果要查询的域名和相关信息已经在缓存中,那么就可以直接返回响应,接下来的查询可以从缓存的位置开始向下进行。相比每次都从根域找起来说,缓存可以减少查询所需的时间。这个缓存机制中有一点需要注意,那就是信息被缓存后,原本的注册信息可能会发生改变,这时缓存中的信息就有可能是不正确的。因此,DNS 服务器中保存的信息都设置有一个有效期,当缓存中的信息超过有效期后,数据就会从缓存中删除。而且,在对查询进行响应时,DNS 服务器也会告知客户端这一响应的结果是来自缓存中还是来自负责管理该域名的 DNS 服务器。

    3.委托协议栈发送消息建立连接

    3.1 创建套接字

    收发数据这里默认以TCP协议为例,首先调用 Socket 库中的特定程序组件创建套接字。套接字创建完成后,协议栈会返回一个描述符 , 应用程序会将收到的描述符存放在内存中。描述符是用来识别不同的套接字的,大家可以作如下理解。我们现在只关注了浏览器访问 Web 服务器的过程,但实际上计算机中会同时进行多个数据的通信操作,比如可以打开两个浏览器窗口,同时访问两台 Web 服务器。这时 ,有两个数据收发操作在同时进行,也就需要创建两个不同的套接字。这个例子说明,同一台计算机上可能同时存在多个套接字,在这样的情况下,我们就需要一种方法来识别出某个特定的套接字,这种方法就是描述符。这时,只要我们出示描述符,协议栈就能够判断出我们希望用哪一个套接字来连接或者收发数据了。

    3.2 使用TCP协议建立连接

    接下来,我们需要委托协议栈将客户端创建的套接字与服务器那边的套接字连接起来。应用程序通过调用 Socket 库中的名为 connect 的程序组件来完成这一操作。这里的要点是当调用 connect 时,需要指定描述符、服务器 IP 地址和端口号这 3 个参数。首先,客户端先创建一个包含表示开始数据收发操作的控制信息的头部。如头部包含很多字段,这里要关注的重点是发送方和接收方的端口号。
    在这里插入图片描述
    当 TCP 头部创建好之后,接下来 TCP 模块会将信息传递给 IP 模块并委托它进行发送 。IP 模块执行网络包发送操作后,网络包就会通过网络到达服务器,然后服务器上的 IP 模块会将接收到的数据传递给 TCP 模块,服务器的 TCP 模块根据 TCP 头部中的信息找到端口号对应的套接字。也就是说,从处于等待连接状态的套接字中找到与 TCP 头部中记录的端口号相同的套接字就可以了。当找到对应的套接字之后,套接字中会写入相应的信息,并将状态改为正在连接 。上述操作完成后,服务器的 TCP 模块会返回响应,这个过程和客户端一样需要在 TCP 头部中设置发送方和接收方端口号以及 SYN 。此外,在返回响应时还需要将 ACK 控制位设为1,这表示已经接收到相应的网络包。网络中经常会发生错误,网络包也会发生丢失,因此双方在通信时必须相互确认网络包是否已经送达 ,而设置ACK就是用来进行这一确认的。接下来,服务器 TCP 模块会将 TCP头部传递给 IP 模块,并委托 IP 模块向客户端返回响应。然后,网络包就会返回到客户端,通过 IP 模块到达 TCP 模块,并通过 TCP 头部的信息确认连接服务器的操作是否成功。如果 SYN 为 1 则表客户端在准确找到服务端之后,也就是搞清楚了应该连接哪个套接字。然后,我们将头部中的控制位的 SYN 比特设置为 1,大家可以认为它表示连接。这时会向套接字中写入服务器的 IP 地址、端口号等信息,同时还会将状态改为连接完毕。到这里,客户端的操作就已经完成,但其实还剩下最后一个步骤。刚才服务器返回响应时将 ACK 设置为 1,相应地,客户端也需要将 ACK 设置为 1 并发回服务器,告诉服务器刚才的响应包已经收到。当这个服务器收到这个返回包之后,连接操作才算全部完成。

    4.发数据

    当控制流程从 connect 回到应用程序之后,接下来就进入数据收发阶段了。数据收发操作是从应用程序调用 write 将要发送的数据交给协议栈开始的,协议栈收到数据后IP模块会在网络包前面添加IP头部和以太网的MAC头部后发送网络包。首先,协议栈并不是一收到数据就马上发送出去,而是会将数据存放在内部的发送缓冲区中,并等待应用程序的下一段数据。避免发送大量的小包,导致网络效率下降,因此需要在数据积累到一定量时再发送出去。至于要积累多少数据才能发送,不同种类和版本的操作系统会有所不同。应用程序在发送数据时可以指定一些选项,比如如果指定“不等待填满缓冲区直接发送”,则协议栈就会按照要求直接发送数据。像浏览器这种会话型的应用程序在向服务器发送数据时,等待填满缓冲区导致延迟会产生很大影响,因此一般会使用直接发送的选项。HTTP 请求消息一般不会很长,一个网络包就能装得下,但如果其中要提交表单数据,长度就可能超过一个网络包所能容纳的数据量就需要对数据进行拆分。根据发送缓冲区中的数据拆分的情况,当判断需要发送这些数据时,就在每 一块数据前面加上TCP头部,并根据套接字中记录的控制信息标记发送方和接收方的端口号,然后交给 IP 模块来执行发送数据的操作。

    4.2 使用ACK号确定包已经收到

    到这里,网络包已经装好数据并发往服务器了,但数据发送操作还没有结束。TCP 具备确认对方是否成功收到网络包,以及当对方没收到时进行重发的功能,因此在发送网络包之后,接下来还需要进行确认操作。首先,客户端在连接时需要计算出与从客户端到服务器方向通信相关的序号初始值,并将这个值发送给服务器。接下来,服务器会通过这个初始值计算出 ACK号并返回给客户端。初始值有可能在通信过程中丢失,因此当服务器收到初始值后需要返回ACK号作为确认。同时,服务器也需要计算出与从服务器到客户端方向通信相关的序号初始值,并将这个值发送给客户端。接下来像刚才一样,客户端也需要根据服务器发来的初始值计算出 ACK 号并返回给服务器。到这里,序号和 ACK 号都已经准备完成了,再往后就可以进入数据收发阶段了。TCP 采用这样的方式确认对方是否收到了数据,在得到对方确认之前,发送过的包都会保存在发送缓冲区中。如果对方没有返回某些包对应的 ACK 号,那么就重新发送这些包。这一机制非常强大。通过这一机制,我们可以确认接收方有没有收到某个包,如果没有收到则重新发送,这样一来,无论网络中发生任何错误,我们都可以发现并采取补救措施(重传网络包)。反过来说,有了这一机制,我们就不需要在其他地方对错误进行补救了

    5.接收响应数据

    和发送数据一样,接收数据也需要将数据暂存到接收缓冲区中,这里的操作过程如下。首先,协议栈尝试从接收缓冲区中取出数据并传递给应用程序,但这个时候请求消息刚刚发送出去,响应消息可能还没返回。响应消息的返回还需要等待一段时间,因此这时接收缓冲区中并没有数据,那么接收数据的操作也就无法继续。这时,协议栈会将应用程序的委托,也就是从接收缓冲区中取出数据并传递给应用程序的工作暂时挂起 ,等服务器返回的响应消息到达之后再继续执行接收操作首先,协议栈会检查收到的数据块和TCP头部的内容,判断是否有数据丢失,如果没有问题则返回 ACK 号。然后,协议栈将数据块暂存到接收缓冲区中,并将数据块按顺序连接起来还原出原始的数据,最后将数据交给应用程序。这个时候就拿到了请求响应数据。

    展开全文
  • 请原谅我把标题中的google.com ... O(∩_∩)O 本文试图回答一个古老的面试问题:当你在浏览器输入google.com并且按下回车之后发生了什么? 不过我们不再局限于平常的回答,而是想办法回答地尽可能具体,不遗漏任...

      本文试图回答一个古老的面试问题:当你在浏览器中输入google.com并且按下回车之后发生了什么?

      不过我们不再局限于平常的回答,而是想办法回答地尽可能具体,不遗漏任何细节。

      这将是一个协作的过程,所以深入挖掘吧,并且帮助我们一起完善它。仍然有大量的细节等待着你来添加,欢迎向我们发送Pull Requset!

      回车键按下

      为了从头开始,我们选择键盘上的回车键被按到最低处作为起点。在这个时刻,一个专用于回车键的电流回路被直接或者通过电容器闭合了,使得少量的电流进入了键盘的逻辑电路系统。这个系统会扫描每个键的状态,对于按键开关的电位弹跳变化进行噪音消除(debounce),并将其转化为键盘码值。在这里,回车的码值是13。键盘控制器在得到码值之后,将其编码,用于之后的传输。现在这个传输过程几乎都是通过通用串行总线(USB)或者蓝牙(Bluetooth)来进行的,以前是通过PS/2或者ADB连接进行。

      USB键盘:

    • 键盘的USB元件通过计算机上的USB接口与USB控制器相连接,USB接口中的第一号针为它提供了5V的电压
    • 键码值存储在键盘内部电路一个叫做"endpoint"的寄存器内
    • USB控制器大概每隔10ms便查询一次"endpoint"以得到存储的键码值数据,这个最短时间间隔由键盘提供
    • 键值码值通过USB串行接口引擎被转换成一个或者多个遵循低层USB协议的USB数据包
    • 这些数据包通过D+针或者D-针(中间的两个针),以最高1.5Mb/s的速度从键盘传输至计算机。速度限制是因为人机交互设备总是被声明成"低速设备"(USB 2.0 compliance)
    • 这个串行信号在计算机的USB控制器处被解码,然后被人机交互设备通用键盘驱动进行进一步解释。之后按键的码值被传输到操作系统的硬件抽象层

      虚拟键盘(触屏设备):

    • 在现代电容屏上,当用户把手指放在屏幕上时,一小部分电流从传导层的静电域经过手指传导,形成了一个回路,使得屏幕上触控的那一点电压下降,屏幕控制器产生一个中断,报告这次“点击”的坐标
    • 然后移动操作系统通知当前活跃的应用,有一个点击事件发生在它的某个GUI部件上了,现在这个部件是虚拟键盘的按钮
    • 虚拟键盘引发一个软中断,返回给OS一个“按键按下”消息
    • 这个消息又返回来向当前活跃的应用通知一个“按键按下”事件

      产生中断[非USB键盘]

      键盘在它的中断请求线(IRQ)上发送信号,信号会被中断控制器映射到一个中断向量,实际上就是一个整型数 。CPU使用中断描述符表(IDT)把中断向量映射到对应函数,这些函数被称为中断处理器,它们由操作系统内核提供。当一个中断到达时,CPU根据IDT和中断向量索引到对应的中端处理器,然后操作系统内核出场了。

      (Windows)一个 WM_KEYDOWN 消息被发往应用程序

      HID把键盘按下的事件传送给 KBDHID.sys 驱动,把HID的信号转换成一个扫描码(Scancode),这里回车的扫描码是VK_RETURN(0x0d)。 KBDHID.sys 驱动和 KBDCLASS.sys (键盘类驱动,keyboard class driver)进行交互,这个驱动负责安全地处理所有键盘和小键盘的输入事件。之后它又去调用 Win32K.sys ,在这之前有可能把消息传递给安装的第三方键盘过滤器。这些都是发生在内核模式。

      Win32K.sys 通过 GetForegroundWindow() API函数找到当前哪个窗口是活跃的。这个API函数提供了当前浏览器的地址栏的句柄。Windows系统的"message pump"机制调用 SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, lParam) 函数, lParam 是一个用来指示这个按键的更多信息的掩码,这些信息包括按键重复次数(这里是0),实际扫描码(可能依赖于OEM厂商,不过通常不会是 VK_RETURN ),功能键(alt, shift, ctrl)是否被按下(在这里没有),以及一些其他状态。

      Windows的 SendMessage API直接将消息添加到特定窗口句柄 hWnd 的消息队列中,之后赋给 hWnd 的主要消息处理函数 WindowProc 将会被调用,用于处理队列中的消息。

      当前活跃的句柄 hWnd 实际上是一个edit control控件,这种情况下,WindowProc 有一个用于处理 WM_KEYDOWN 消息的处理器,这段代码会查看 SendMessage 传入的第三个参数 wParam ,因为这个参数是 VK_RETURN ,于是它知道用户按下了回车键。

      (Mac OS X)一个 KeyDown NSEvent被发往应用程序

      中断信号引发了I/O Kit Kext键盘驱动的中断处理事件,驱动把信号翻译成键码值,然后传给OS X的 WindowServer进程。然后, WindowServer 将这个事件通过Mach端口分发给合适的(活跃的,或者正在监听的)应用程序,这个信号会被放到应用程序的消息队列里。队列中的消息可以被拥有足够高权限的线程使用 mach_ipc_dispatch 函数读取到。这个过程通常是由 NSApplication 主事件循环产生并且处理的,通过 NSEventType 为 KeyDown 的 NSEvent 。

      (GNU/Linux)Xorg 服务器监听键码值

      当使用图形化的 X Server 时,X Server会按照特定的规则把键码值再一次映射,映射成扫描码。当这个映射过程完成之后, X Server 把这个按键字符发送给窗口管理器(DWM,metacity, i3等等),窗口管理器再把字符发送给当前窗口。当前窗口使用有关图形API把文字打印在输入框内。

      解析URL

    • 浏览器通过URL能够知道下面的信息:

      • Protocol "http"

        使用HTTP协议

      • Resource "/"

        请求的资源是主页(index)

      输入的是URL还是搜索的关键字?

      当协议或主机名不合法时,浏览器会将地址栏中输入的文字传给默认的搜索引擎。大部分情况下,在把文字传递给搜索引擎的时候,URL会带有特定的一串字符,用来告诉搜索引擎这次搜索来自这个特定浏览器。

      检查HSTS列表···

    • 浏览器检查自带的“预加载HSTS(HTTP严格传输安全)”列表,这个列表里包含了那些请求浏览器只使用HTTPS进行连接的网站
    • 如果网站在这个列表里,浏览器会使用HTTPS而不是HTTP协议,否则,最初的请求会使用HTTP协议发送
    • 注意,一个网站哪怕不在HSTS列表里,也可以要求浏览器对自己使用HSTS政策进行访问。浏览器向网站发出第一个HTTP请求之后,网站会返回浏览器一个响应,请求浏览器只使用HTTPS发送请求。然而,就是这第一个HTTP请求,却可能会使用户收到 downgrade attack 的威胁,这也是为什么现代浏览器都预置了HSTS列表。

      转换非ASCII的Unicode字符

    • 浏览器检查输入是否含有不是 a-z, A-Z0-9, - 或者 . 的字符
    • 这里主机名是 google.com ,所以没有非ASCII的字符,如果有的话,浏览器会对主机名部分使用 Punycode 编码

      DNS查询···

    • 浏览器检查域名是否在缓存当中
    • 如果缓存中没有,就去调用 gethostbynme 库函数(操作系统不同函数也不同)进行查询
    • gethostbyname 函数在试图进行DNS解析之前首先检查域名是否在本地Hosts里,Hosts的位置 不同的操作系统有所不同
    • 如果 gethostbyname 没有这个域名的缓存记录,也没有在 hosts 里找到,它将会向DNS 服务器发送一条DNS查询请求。DNS服务器是由网络通信栈提供的,通常是本地路由器或者ISP的缓存DNS服务器。
    • 查询本地 DNS 服务器
    • 如果DNS服务器和我们的主机在同一个子网内,系统会按照下面的 ARP 过程对 DNS 服务器进行 ARP查询
    • 如果DNS服务器和我们的主机在不同的子网,系统会按照下面的 ARP 过程对默认网关进行查询

      ARP

      要想发送ARP广播,我们需要有一个目标IP地址,同时还需要知道用于发送ARP广播的接口的Mac地址。

    • 首先查询ARP缓存,如果缓存命中,我们返回结果:目标IP = MAC

      如果缓存没有命中:

    • 查看路由表,看看目标IP地址是不是在本地路由表中的某个子网内。是的话,使用跟那个子网相连的接口,否则使用与默认网关相连的接口。
    • 查询选择的网络接口的MAC地址
    • 我们发送一个二层ARP请求:

      ARP Request:

    Sender MAC: interface:mac:address:here
    Sender IP: interface.ip.goes.here
    Target MAC: FF:FF:FF:FF:FF:FF (Broadcast)
    Target IP: target.ip.goes.here

      根据连接主机和路由器的硬件类型不同,可以分为以下几种情况:

      直连:

    • 如果我们和路由器是直接连接的,路由器会返回一个 ARP Reply (见下面)。

      集线器:

    • 如果我们连接到一个集线器,集线器会把ARP请求向所有其它端口广播,如果路由器也“连接”在其中,它会返回一个 ARP Reply 。

      交换机:

    • 如果我们连接到了一个交换机,交换机会检查本地 CAM/MAC 表,看看哪个端口有我们要找的那个MAC地址,如果没有找到,交换机会向所有其它端口广播这个ARP请求。
    • 如果交换机的MAC/CAM表中有对应的条目,交换机会向有我们想要查询的MAC地址的那个端口发送ARP请求
    • 如果路由器也“连接”在其中,它会返回一个 ARP Reply

      ARP Reply:

    Sender MAC: target:mac:address:here
    Sender IP: target.ip.goes.here
    Target MAC: interface:mac:address:here
    Target IP: interface.ip.goes.here

      现在我们有了DNS服务器或者默认网关的IP地址,我们可以继续DNS请求了:

    • 使用53端口向DNS服务器发送UDP请求包,如果响应包太大,会使用TCP
    • 如果本地/ISP DNS服务器没有找到结果,它会发送一个递归查询请求,一层一层向高层DNS服务器做查询,直到查询到起始授权机构,如果找到会把结果返回

      使用套接字

      当浏览器得到了目标服务器的IP地址,以及URL中给出来端口号(http协议默认端口号是80, https默认端口号是443),它会调用系统库函数 socket ,请求一个TCP流套接字,对应的参数是 AF_INET 和 SOCK_STREAM 。

    • 这个请求首先被交给传输层,在传输层请求被封装成TCP segment。目标端口会会被加入头部,源端口会在系统内核的动态端口范围内选取(Linux下是ip_local_port_range)
    • TCP segment被送往网络层,网络层会在其中再加入一个IP头部,里面包含了目标服务器的IP地址以及本机的IP地址,把它封装成一个TCP packet。
    • 这个TCP packet接下来会进入链路层,链路层会在封包中加入frame头部,里面包含了本地内置网卡的MAC地址以及网关(本地路由器)的MAC地址。像前面说的一样,如果内核不知道网关的MAC地址,它必须进行ARP广播来查询其地址。

      到了现在,TCP封包已经准备好了,可是使用下面的方式进行传输:

      对于大部分家庭网络和小型企业网络来说,封包会从本地计算机出发,经过本地网络,再通过调制解调器把数字信号转换成模拟信号,使其适于在电话线路,有线电视光缆和无线电话线路上传输。在传输线路的另一端,是另外一个调制解调器,它把模拟信号转换回数字信号,交由下一个 网络节点 处理。节点的目标地址和源地址将在后面讨论。

      大型企业和比较新的住宅通常使用光纤或直接以太网连接,这种情况下信号一直是数字的,会被直接传到下一个 网络节点 进行处理。

      最终封包会到达管理本地子网的路由器。在那里出发,它会继续经过自治区域的边界路由器,其他自治区域,最终到达目标服务器。一路上经过的这些路由器会从IP数据报头部里提取出目标地址,并将封包正确地路由到下一个目的地。IP数据报头部TTL域的值每经过一个路由器就减1,如果封包的TTL变为0,或者路由器由于网络拥堵等原因封包队列满了,那么这个包会被路由器丢弃。

      上面的发送和接受过程在TCP连接期间会发生很多次:

    • 客户端选择一个初始序列号(ISN),将设置了SYN位的封包发送给服务器端,表明自己要建立连接并设置了初始序列号

    • 服务器端接受到SYN包,如果它可以建立连接:
      • 服务器端选择它自己的初始序列号
      • 服务器端设置SYN位,表明自己选择了一个初始序列号
      • 服务器端把 (客户端ISN + 1) 复制到ACK域,并且设置ACK位,表明自己接收到了客户端的第一个封包
    • 客户端通过发送下面一个封包来确认这次连接:
      • 自己的序列号+1
      • 接收端ACK+1
      • 设置ACK位
    • 数据通过下面的方式传输:
      • 当一方发送了N个Bytes的数据之后,将自己的SEQ序列号也增加N
      • 另一方确认接收到这个数据包(或者一系列数据包)之后,它发送一个ACK包,ACK的值设置为接收到的数据包的最后一个序列号
    • 关闭连接时:
      • 要关闭连接的一方发送一个FIN包
      • 另一方确认这个FIN包,并且发送自己的FIN包
      • 要关闭的一方使用ACK包来确认接收到了FIN

      UDP 数据包

      TLS 握手

    • 客户端发送一个 Client hello 消息到服务器端,消息中同时包含了它的TLS版本,可用的加密算法和压缩算法。
    • 服务器端向客户端返回一个 Server hello 消息,消息中包含了服务器端的TLS版本,服务器选择了哪个加密和压缩算法,以及服务器的公开证书,证书中包含了公钥。客户端会使用这个公钥加密接下来的握手过程,直到协商生成一个新的对称密钥
    • 客户端根据自己的信任CA列表,验证服务器端的证书是否有效。如果有效,客户端会生成一串伪随机数,使用服务器的公钥加密它。这串随机数会被用于生成新的对称密钥
    • 服务器端使用自己的私钥解密上面提到的随机数,然后使用这串随机数生成自己的对称主密钥
    • 客户端发送一个 Finished 消息给服务器端,使用对称密钥加密这次通讯的一个散列值
    • 服务器端生成自己的 hash 值,然后解密客户端发送来的信息,检查这两个值是否对应。如果对应,就向客户端发送一个 Finished 消息,也使用协商好的对称密钥加密
    • 从现在开始,接下来整个 TLS 会话都使用对称秘钥进行加密,传输应用层(HTTP)内容

      TCP 数据包

      HTTP 协议···

      如果浏览器是Google出品的,它不会使用HTTP协议来获取页面信息,而是会与服务器端发送请求,商讨使用SPDY协议。

      如果浏览器使用HTTP协议,它会向服务器发送这样的一个请求:

    GET / HTTP/1.1Host: google.com[其他头部]

      “其他头部”包含了一系列的由冒号分割开的键值对,它们的格式符合HTTP协议标准,它们之间由一个换行符分割开来。这里我们假设浏览器没有违反HTTP协议标准的bug,同时浏览器使用 HTTP/1.1 协议,不然的话头部可能不包含 Host 字段,同时 GET 请求中的版本号会变成 HTTP/1.0 或者 HTTP/0.9 。

    HTTP/1.1 定义了“关闭连接”的选项 "close",发送者使用这个选项指示这次连接在响应结束之后会断开:

    Connection:close

      不支持持久连接的 HTTP/1.1 必须在每条消息中都包含 "close" 选项。

      在发送完这些请求和头部之后,浏览器发送一个换行符,表示要发送的内容已经结束了。

      服务器端返回一个响应码,指示这次请求的状态,响应的形式是这样的:

    200 OK[response headers]

      然后是一个换行,接下来有效载荷(payload),也就是 www.google.com 的HTML内容。服务器下面可能会关闭连接,如果客户端请求保持连接的话,服务器端会保持连接打开,以供以后的请求重用。

      如果浏览器发送的HTTP头部包含了足够多的信息(例如包含了 Etag 头部,以至于服务器可以判断出,浏览器缓存的文件版本自从上次获取之后没有再更改过,服务器可能会返回这样的响应:

    304 Not Modified[response headers]

      这个响应没有有效载荷,浏览器会从自己的缓存中取出想要的内容。

      在解析完HTML之后,浏览器和客户端会重复上面的过程,直到HTML页面引入的所有资源(图片,CSS,favicon.ico等等)全部都获取完毕,区别只是头部的 GET / HTTP/1.1 会变成 GET /$(相对www.google.com的URL) HTTP/1.1 。

      如果HTML引入了 www.google.com 域名之外的资源,浏览器会回到上面解析域名那一步,按照下面的步骤往下一步一步执行,请求中的 Host 头部会变成另外的域名。

      HTTP服务器请求处理

      HTTPD(HTTP Daemon)在服务器端处理请求/相应。最常见的 HTTPD 有 Linux 上常用的 Apache 和 nginx,与 Windows 上的 IIS。

    • HTTPD接收请求

    • 服务器把请求拆分为以下几个参数:
      • HTTP请求方法(GET, POST, HEAD, PUT 和 DELETE )。在访问Google这种情况下,使用的是GET方法
      • 域名:google.com
      • 请求路径/页面:/ (我们没有请求google.com下的指定的页面,因此 / 是默认的路径)
    • 服务器验证其上已经配置了google.com的虚拟主机

    • 服务器验证google.com接受GET方法

    • 服务器验证该用户可以使用GET方法(根据IP地址,身份信息等)

    • 如果服务器安装了 URL 重写模块(例如 Apache 的 mod_rewrite 和 IIS 的 URL Rewrite),服务器会尝试匹配重写规则,如果匹配上的话,服务器会按照规则重写这个请求

    • 服务器根据请求信息获取相应的响应内容,这种情况下由于访问路径是 "/" ,会访问首页文件。(你可以重写这个规则,但是这个是最常用的)

    • 服务器会使用指定的处理程序分析处理这个文件,比如假设Google使用PHP,服务器会使用PHP解析index文件,并捕获输出,把PHP的输出结果给请求者

      浏览器背后的故事

      当服务器提供了资源之后(HTML,CSS,JS,图片等),浏览器会执行下面的操作:

    • 解析 HTML,CSS,JS
    • 渲染——构建 DOM 树 -> 渲染 -> 布局 -> 绘制

      浏览器

      浏览器的功能是从服务器上取回你想要的资源,然后展示在浏览器窗口当中。资源通常是 HTML 文件,也可能是 PDF,图片,或者其他类型的内容。资源的位置通过用户提供的 URI(Uniform Resource Identifier) 来确定。

      浏览器解释和展示 HTML 文件的方法,在 HTML 和 CSS 的标准中有详细介绍。这些标准由 Web 标准组织 W3C(World Wide Web Consortium) 维护。

      不同浏览器的用户界面大都十分接近,有很多共同的 UI 元素:

    • 一个地址栏
    • 后退和前进按钮
    • 书签选项
    • 刷新和停止按钮
    • 主页按钮

      浏览器高层架构

      组成浏览器的组件有:

    • 用户界面 用户界面包含了地址栏,前进后退按钮,书签菜单等等,除了请求页面之外所有你看到的内容都是用户界面的一部分
    • 浏览器引擎 浏览器引擎负责让 UI 和渲染引擎协调工作
    • 渲染引擎 渲染引擎负责展示请求内容。如果请求的内容是 HTML,渲染引擎会解析 HTML 和 CSS,然后将内容展示在屏幕上
    • 网络组件 网络组件负责网络调用,例如 HTTP 请求等,使用一个平台无关接口,下层是针对不同平台的具体实现
    • UI后端 UI后端用于绘制基本 UI 组件,例如下拉列表框和窗口。UI 后端暴露一个统一的平台无关的接口,下层使用操作系统的 UI 方法实现
    • Javascript 解释器 Javascript 解释器用于解析和执行 Javascript 代码
    • 数据存储 数据存储组件是一个持久层。浏览器可能需要在本地存储各种各样的数据,例如 Cookie 等。浏览器也需要支持诸如 localStorage,IndexedDB,WebSQL 和 FileSystem 之类的存储机制

      HTML 解析

      浏览器渲染引擎从网络层取得请求的文档,一般情况下文档会分成8kB大小的分块传输。

      HTML解析器的主要工作是对HTML文档进行解析,生成解析树。

      解析树是以DOM元素以及属性为节点的树。DOM是文档对象模型(Document Object Model)的缩写,它是HTML文档的对象表示,同时也是HTML元素面向外部(如Javascript)的接口。树的根部是"Document"对象。整个DOM和HTML文档几乎是一对一的关系。

      解析算法

      HTML不能使用常见的自顶向下或自底向上方法来进行分析。主要原因有以下几点:

    • 语言本身的“宽容”特性
    • HTML本身可能是残缺的,对于常见的残缺,浏览器需要有传统的容错机制来支持它们
    • 解析过程需要反复。对于其他语言来说,源码不会在解析过程中发生变化,但是对于HTML来说,动态代码,例如脚本元素中包含的 document.write() 方法会在源码中添加内容,也就是说,解析过程实际上会改变输入的内容

      由于不能使用常用的解析技术,浏览器创造了专门用于解析HTML的解析器。解析算法在 HTML5 标准规范中有详细介绍,算法主要包含了两个阶段:标记化(tokenization)和树的构建。

      解析结束之后

      浏览器开始加载网页的外部资源(CSS,图像,Javascript 文件等)。

      此时浏览器把文档标记为“可交互的”,浏览器开始解析处于“推迟”模式的脚本,也就是那些需要在文档解析完毕之后再执行的脚本。之后文档的状态会变为“完成”,浏览器会进行“加载”事件。

      注意解析 HTML 网页时永远不会出现“语法错误”,浏览器会修复所有错误,然后继续解析。

      执行同步 Javascript 代码。

      CSS 解析

    • 根据 CSS词法和句法 分析CSS文件和 <style> 标签包含的内容
    • 每个CSS文件都被解析成一个样式表对象,这个对象里包含了带有选择器的CSS规则,和对应CSS语法的对象
    • CSS解析器可能是自顶向下的,也可能是使用解析器生成器生成的自底向上的解析器

      页面渲染

    • 通过遍历DOM节点树创建一个“Frame 树”或“渲染树”,并计算每个节点的各个CSS样式值
    • 通过累加子节点的宽度,该节点的水平内边距(padding)、边框(border)和外边距(margin),自底向上的计算"Frame 树"中每个节点首的选(preferred)宽度
    • 通过自顶向下的给每个节点的子节点分配可行宽度,计算每个节点的实际宽度
    • 通过应用文字折行、累加子节点的高度和此节点的内边距(padding)、边框(border)和外边距(margin),自底向上的计算每个节点的高度
    • 使用上面的计算结果构建每个节点的坐标
    • 当存在元素使用 floated,位置有 absolutely 或 relatively 属性的时候,会有更多复杂的计算,详见http://dev.w3.org/csswg/css2/ 和 http://www.w3.org/Style/CSS/current-work
    • 创建layer(层)来表示页面中的哪些部分可以成组的被绘制,而不用被重新栅格化处理。每个帧对象都被分配给一个层
    • 页面上的每个层都被分配了纹理(?)
    • 每个层的帧对象都会被遍历,计算机执行绘图命令绘制各个层,此过程可能由CPU执行栅格化处理,或者直接通过D2D/SkiaGL在GPU上绘制
    • 上面所有步骤都可能利用到最近一次页面渲染时计算出来的各个值,这样可以减少不少计算量
    • 计算出各个层的最终位置,一组命令由 Direct3D/OpenGL发出,GPU命令缓冲区清空,命令传至GPU并异步渲染,帧被送到Window Server。

      GPU 渲染

    • 在渲染过程中,图形处理层可能使用通用用途的CPU,也可能使用图形处理器GPU
    • 当使用GPU用于图形渲染时,图形驱动软件会把任务分成多个部分,这样可以充分利用GPU强大的并行计算能力,用于在渲染过程中进行大量的浮点计算。

      Window Server

      后期渲染与用户引发的处理

      渲染结束后,浏览器根据某些时间机制运行JavaScript代码(比如Google Doodle动画)或与用户交互(在搜索栏输入关键字获得搜索建议)。类似Flash和Java的插件也会运行,尽管Google主页里没有。这些脚本可以触发网络请求,也可能改变网页的内容和布局,产生又一轮渲染与绘制。


    1、浏览器会根据输入的URL来分析是否符合URL标准,如果不符合的话,会交给搜索引擎。

    2、如果是正确的URL,那么浏览器会检索该主机的HOST列表,如果有该域名的IP的话,就万事大吉,没有的话,就需要去DNS解析了,先请求本地服务器,如果本地服务器也没有该域名的IP的话,那么由本地服务器依次向上请求,根服务器,com服务器,百度服务器,直到找到baidu.com的IP地址,然后返回给本地服务器,再由本地服务器返回给用户代理。      (另外DNS和CDN的区别,CDN是利用DNS的重定向技术来进行的,也就是说,在全国很多地方布置一些子服务器,然后根据用户的距离及服务器的负载来分配服务器,达到减少连接需时的目的)

    3、现在有了baidu.com的IP地址,但是我们知道建立通信是需要双方的IP和MAC地址的,那么我们肯定无法获取baidu.com的MAC地址,这时候就需要用ARP协议来获取网关的MAC地址,然后把请求发送给网关,再由网关发送给baidu.com服务器。

    4、先由客户端发送一次随机数字,然后服务器接收到后,把该数字加1,然后自己再生成一个随机数字,然后再加上一个ACK回复,再返回给客户端,客户端收到后,也回复一个ACK,并同时可以发送数据。这就是TCP的三次握手。(当然如果是从下载的话,就要等到服务器接受到客户端的ACK后,就会发送数据给客户端)

    5、解析 HTML,CSS,JS     渲染——构建 DOM 树 -> 渲染 -> 布局 -> 绘制


    1.检查URL正误

    2.浏览器查找域名的IP地址 浏览器 系统 路由器 DNS服务器从跟域名服务器开始进行递归搜索

    3.有了IP地址,需要MAC地址,要用ARP协议来获取网关的MAC地址,然后把请求发送给网关,再由网关发送给baidu.com服务器。

    4.TCP三次握手,建立连接。

    5. 浏览器给web服务器发送一个HTTP get请求

    6. 服务器给浏览器的永久重定向响应

    7. 浏览器跟踪重定向地址

    8. 服务器“处理”请求

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

    10. 浏览器开始显示HTML



    展开全文
  • 1、浏览器根据域名(主机名)通过DNS服务器查询域名对应的服务器的IP地址2、浏览器主机根据IP地址与服务器建立TCP连接。3、浏览器将访问请求封装为一个HTTP请求报文,通过TCP协议发送给服务器。4、服务器收到请求并...

    1、浏览器根据域名(主机名)通过DNS服务器查询域名对应的服务器的IP地址

    2、浏览器主机根据IP地址与服务器建立TCP连接。

    3、浏览器将访问请求封装为一个HTTP请求报文,通过TCP协议发送给服务器。

    4、服务器收到请求并响应,生成一个HTTP响应报文,通过TCP协议发送给浏览器主机。

    5、浏览器得到响应报文之后,对响应报文进行解析。


    6、浏览器异步请求其他资源


    展开全文
  • 作为一个软件开发者,你一定会对网络应用如何工作有一个完整的... 首先嘛,你得在浏览器输入网址:2. 浏览器查找域名的IP地址导航的第一步是通过访问的域名找出其IP地址。DNS查找过程如下:* 浏览器缓存 – 浏览器
    作为一个软件开发者,你一定会对网络应用如何工作有一个完整的层次化的认知,同样这里也包括这些应用所用到的技术:像浏览器,HTTP,HTML,网络服务器,需求处理等等。
    
    本文将更深入的研究当你输入一个网址的时候,后台到底发生了一件件什么样的事~
    1. 首先嘛,你得在浏览器里输入要网址:



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


    导航的第一步是通过访问的域名找出其IP地址。DNS查找过程如下:
    * 浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。
    * 系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。
    * 路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。
    * ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
    * 递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会 有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。

    DNS递归查找如下图所示:
    500pxAn_example_of_theoretical_DNS_recursion_svg.png


    DNS有一点令人担忧,这就是像wikipedia.org 或者 facebook.com这样的整个域名看上去只是对应一个单独的IP地址。还好,有几种方法可以消除这个瓶颈:
    * 循环 DNS 是DNS查找时返回多个IP时的解决方案。举例来说,Facebook.com实际上就对应了四个IP地址。
    * 负载平衡器 是以一个特定IP地址进行侦听并将网络请求转发到集群服务器上的硬件设备。 一些大型的站点一般都会使用这种昂贵的高性能负载平衡器。
    * 地理 DNS 根据用户所处的地理位置,通过把域名映射到多个不同的IP地址提高可扩展性。这样不同的服务器不能够更新同步状态,但映射静态内容的话非常好。
    * Anycast 是一个IP地址映射多个物理主机的路由技术。 美中不足,Anycast与TCP协议适应的不是很好,所以很少应用在那些方案中。

    大多数DNS服务器使用Anycast来获得高效低延迟的DNS查找。
    3. 浏览器给web服务器发送一个HTTP请求

    因为像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 and Accept-Encoding 头). Connection头要求服务器为了后边的请求不要关闭TCP连接。
    请求中也包含浏览器存储的该域名的cookies。可能你已经知道,在不同页面请求当中,cookies是与跟踪一个网站状态相匹配的键值。这样cookies会存储登录用户名,服务器分配的密码和一些用户设置等。Cookies会以文本文档形式存储在客户机里,每次请求时发送给服务器
    用来看原始HTTP请求及其相应的工具很多。作者比较喜欢使用fiddler,当然也有像FireBug这样其他的工具。这些软件在网站优 化时会帮上很大忙。
    除了获取请求,还有一种是发送请求,它常在提交表单用到。发送请求通过URL传递其参数(e.g.:HTTP://robozzle.com/puzzle.aspx?id=85)。发送请求在请求正文头之后发送其参数。

    像“HTTP://facebook.com/”中的斜杠是至关重要的。这种情况下,浏览器能安全的添加斜杠。而像“HTTP: //example.com/folderOrFile”这样的地址,因为浏览器不清楚folderOrFile到底是文件夹还是文件,所以不能自动添加 斜杠。这时,浏览器就不加斜杠直接访问地址,服务器会响应一个重定向,结果造成一次不必要的握手。
    4. facebook服务的永久重定向响应

    图中所示为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/”。
    为什么服务器一定要重定向而不是直接发会用户想看的网页内容呢?这个问题有好多有意思的答案。
    其中一个原因跟搜索引擎排名有 关。你看,如果一个页面有两个地址,就像HTTP://www.igoro.com/ 和HTTP://igoro.com/,搜索引擎会认为它们是两个网站,结果造成每一个的搜索链接都减少从而降低排名。而搜索引擎知道301永久重定向是 什么意思,这样就会把访问带www的和不带www的地址归到同一个网站排名下。
    还有一个是用不同的地址会造成缓存友好性变差。当一个页面有好几个名字时,它可能会在缓存里出现好几次。
    5. 浏览器跟踪重定向地址


    现在,浏览器知道了 “HTTP://www.facebook.com/”才是要访问的正确地址,所以它会发送另一个获取请求:
    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

    头信息以之前请求中的意义相同。
    6. 服务器“处理”请求


    服务器接收到获取请求,然后处理并返回一个响应。
    这表面上看起来是一个顺向的任务,但其实这中间发生了很多有意思的东西- 就像作者博客这样简单的网站,何况像facebook那样访问量大的网站呢!
    * Web 服务器软件web服务器软件(像IIS和阿帕奇)接收到HTTP请求,然后确定执行什么请求处理来处理它。请求处理就 是一个能够读懂请求并且能生成HTML来进行响应的程序(像ASP.NET,PHP,RUBY…)。
    举 个最简单的例子,需求处理可以以映射网站地址结构的文件层次存储。像HTTP://example.com/folder1/page1.aspx这个地 址会映射/httpdocs/folder1/page1.aspx这个文件。web服务器软件可以设置成为地址人工的对应请求处理,这样 page1.aspx的发布地址就可以是HTTP://example.com/folder1/page1* 请求处理请求处理阅读 请求及它的参数和cookies。它会读取也可能更新一些数据,并讲数据存储在服务器上。然后,需求处理会生成一个HTML响应。
    所 有动态网站都面临一个有意思的难点 -如何存储数据。小网站一半都会有一个SQL数据库来存储数据,存储大量数据和/或访问量大的网站不得不找一些办法把数据库分配到多台机器上。解决方案有:sharding (基于主键值讲数据表分散到多个数据库中),复制,利用弱语义一致性的简化数据库。
    委托工作给批处理是一个廉价保持数据更新的技术。举例来讲,Fackbook得及时更新新闻feed,但数据支持下的“你可能认识的人”功能只需要每晚更新(作者猜测是这样的,改功能如何完善不得而知)。批处理作业更新会导致一些不太重要的数据陈旧,但能使数据更新耕作更快更简洁。7. 服务器发回一个HTML响应


    图中为服务器生成并返回的响应:
    HTTP/1.1 200 OKCache-Control: private, no-store, no-cache, must-revalidate, post-check=0,pre-check=0Expires: Sat, 01 Jan 2000 00:00:00 GMTP3P: CP=”DSP LAW”Pragma: no-cacheContent-Encoding: gzipContent-Type: text/html; charset=utf-8X-Cnection: closeTransfer-Encoding: chunkedDate: Fri, 12 Feb 2010 09:05:55 GMT
    2b3Tn@[...]
    整个响应大小为35kB,其中大部分在整理后以blob类型传输。
    内容编码头告诉浏览器整个响应体用 gzip算法进行压缩。解压blob块后,你可以看到如下期望的HTML:
    HTTP://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>lang=”en” id=”facebook”>

    关于压缩,头信息说明了是否缓存这个页面,如果缓存的话如何去做,有什么cookies要去设置(前面这个响应里没有这点)和隐私信息等 等。
    请注意报头中把Content-type设置为“text/html”。报头让浏览器将该响应内容以HTML形式呈现,而不是以文件形式下 载它。浏览器会根据报头信息决定如何解释该响应,不过同时也会考虑像URL扩展内容等其他因素。8. 浏览器开始显示HTML
    在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了:


    9. 浏览器发送获取嵌入在HTML中的对象


    在浏览器显示HTML时,它会注意到需要获取其他地址内容的标签。这时,浏览器会发送一个获取请求来重新获得这些文件。
    下面是几个我们访问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一次的时候,响应的 服务器可能就不一样,这说明幕后的负载平衡开始起作用了。10. 浏览器发送异步(AJAX)请求


    在Web 2.0伟大精神的指引下,页面显示完成后客户端仍与服务器端保持着联系。
    以 Facebook聊天功能为例,它会持续与服务器保持联系来及时更新你那些亮亮灰灰的好友状态。为了更新这些头像亮着的好友状态,在浏览器中执行的 JavaScript代码会给服务器发送异步请求。这个异步请求发送给特定的地址,它是一个按照程式构造的获取或发送请求。还是在Facebook这个例子中,客户端发送给HTTP://www.facebook.com/ajax/chat/buddy_list.php一个发布请求来获取你好友里哪个 在线的状态信息。
    提起这个模式,就必须要讲讲”AJAX”– “异步JavaScript 和 XML”,虽然服务器为什么用XML格式来进行响应也没有个一清二白的原因。再举个例子吧,对于异步请求,Facebook会返回一些 JavaScript的代码片段。
    除了其他,fiddler这个工具能够让你看到浏览器发送的异步请求。事实上,你不仅可以被动的做为这些请求的看客,还能主动出击修改和重 新发送它们。AJAX请求这么容易被蒙,可着实让那些计分的在线游戏开发者们郁闷的了。(当然,可别那样骗人家~)
    Facebook聊天功能提供了关于AJAX一个有意思的问题案例:把数据从服务器端推送到客户端。因为HTTP是一个请求-响应协议,所 以聊天服务器不能把新消息发给客户。取而代之的是客户端不得不隔几秒就轮询下服务器端看自己有没有新消息。
    这些情况发生时长轮询是个减轻服务器负载挺有趣的技术。如果当被轮询时服务器没有新消息,它就不理这个客户端。而当尚未超时的情况下收到了 该客户的新消息,服务器就会找到未完成的请求,把新消息做为响应返回给客户端。总结一下
    希望看了本文,你能明白不同的网络模块是如何协同工作的
    本篇文章来源于 站长资讯网 原文链接:http://www.chinahtml.com/1007/127890385919293_2.html

     

     

     

     

    我们似乎每天都要做这样一件事情,打开一个浏览器,输入网址,回车,一个空白的页面顿时有了东西,它可能是百度之类的搜索页面,或是一个挤满了文字和图片的门户网站。从我们打开浏览器,到我们看到我们想看的内容,这过程究竟发生了什么?
    下面我们就从三个方面理解这个过程,一个是浏览器,二个是服务器,第三个是浏览器和服务器之间通信的协议。在理解这三方面之前我们必须先搞明白将这三方面联系起来的一个词:web。 

    1,world wide web 
    我们通常所说的web就是指world wide web。一般来讲,这一种通过浏览器来访问资源的技术。我们经常说的上网,应该大部都是指的是上万维网(web),但是我们经常将万维网和因特网(Internet)搞混。因特网是一种网络互连的技术,它更指的是物理层面上的互连,而万维网应该算是跑在因特网上的一种服务。
    我们通常通过浏览器还访问web,我们常见到的网页中包含超文本,图片,视频音频等各项内容。向我们提供这些资源的是一个一个的站点,通过互联网,这些站点相互连接起来。我们通过超链接从一个网页访问到另外一个网页,从一个站点到另外一个站点,所有的这一切组成一个庞大的网,这就是web。
    支持web的技术,首先是底层的网络,因为web就是建立在Internet之上,web的基本协议是HTTP协议,它跑在TCP上的协议之上,而TCP协议又需要IP协议的支持,IP协议又要由底层链路来支撑,所以我们可以从高到第看到这样一个协议栈 http->tcp->ip->连路层协议。要理解web到ip就已经足够了。
    我们可以想一想web上的资源有哪些? 首先是文本,后来添加了图片,到现在的各种音频视频资源,所有互联网上的资源都要通过一个叫做URI的东西还标记,当然了我们更常见是URL。现在也不必纠结于两者有何不同,URL就是URI的一个子集,URL给了我们资源的地址,所以我们能够找到它。
    现在看一个URL:这是一个图片的url。它是按照这样的语法来定义:scheme://domain:port/path?query_string#fragment_id.scheme就是协议,在浏览器里通常是http,例子中的是https是一种由HTTP和SSL/TLS组合起来的应用,用以提供加密通信和对网络服务器的身份验证(http://zh.wikipedia.org/zh/HTTPS )。然后就是域名,每个站点都至少有一个域名,上面例子上的域名部分是www.google.com.hk,这个域名也是分为三部分的,www是主机名,com.hk算是顶级域名,除了com还有cn,net等。域名后面是端口号默认为80,通常被省略,这是服务器端服务器软件侦听的端口,也是TCP里面一个端口号的值。然后就是path,资源在服务器上的路径。最后问号部分的客户端利用url传给服务器的一些参数值,通常值比较少,不太重要时这么做。
    2,协议
    (1)HTTP协议
    web里最重要的协议就是HTTP协议,对于经典的ISO七层网络模型来说, HTTP处于最高层--应用层。HTTP应用的模型是client/server模型。因此对应着两种HTTP消息类型,request和response。客户端向服务器发出请求,服务器向客户端发回请求。下面看一下两种类型消息的格式:



     
    下面分别进行解释。
    首先是HTTP Request Message
    请求行:请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本。请求方法常见的有:GET POST HEAD PUT等。
    消息报头:在普通报头中,有少数报头域用于所有的请求和响应消息,但并不用于被传输的实体,只用于传输的消息。 请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。 请求和响应消息都可以传送一个实体。一个实体由实体报头域和实体正文组成,但并不是说实体报头域和实体正文要在一起发送,可以只发送实体报头域。实体报头定义了关于实体正文(eg:有无实体正文)和请求所标识的资源的元信息。 POST请求的内容放在实体正文中。 
    HTTP Response Message
    状态行:最主要的一个字段是服务器响应代码。比如,200 OK ,400 Bad Request ,401 Unauthorized ,403 Forbidden ,404 Not Found ,500 Internal Server Error ,503 Server Unavailable
    消息报头:普通报头和实体报头与 请求报头的类似。有区别的在于响应包头,响应报头允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和对Request-URI所标识的资源进行下一步访问的信息。
    (这部分说的比较粗略,网上的资源比较多,可以参考这一篇:http://blog.csdn.net/gueter/article/details/1524447 和http://book.51cto.com/art/200902/109036.htm )
    下面是ethereal抓到的一个get报文,post报文和响应报文,可以大概看一下。
     
     
     
    (2)TCP协议
    HTTP协议基于TCP协议,也就是HTTP的所有内容将作为TCP的实体被封装到TCP报文里面。TCP协议是面向连接,可靠的传输机制。也就是说客户端在与服务器交互数据的过程中会有一个连接建立和释放的过程,看上面的Http头部字段可以看到相关的字段。TCP有强大的窗口机制能够适应发送方和接收方的发送接收能力,也能根据整个网络状况进行调整。
    (3)IP协议
    IP协议处于整个TCP/IP协议族的承上启下地位。我们知道因特网上主机是靠一个32位的ip地址来定位的,HTTP用的URL也算是地址,但是比较高级,IP协议是理解不了的,所以需要一个从URL到IP的转换,这个过程通过DNS(域名查询系统)协议完成。我们用的每一台电脑上都配置了DNS服务器的地址,如果没有配置那么你的网关默认充当了,当我们有一个URL想知道对应的IP时就需要向DNS服务器发送查询请求了,它会把查询的结果发回。
    2,浏览器
    在web的世界里最不能少的角色就是浏览器。前面我们说到HTTP协议,HTTP消息有两种,request和response。浏览器的主要工作就是发送http request报文和接收处理http response报文。没有看过浏览器的开源文档,但是我觉得一个软件只要完成下面几件事,基本上就可以称的上一个浏览器了。
    (1)能够根据用户的请求生成合适的HTTP REQUEST报文。比如用户在浏览器地址栏上输入地址进行访问,浏览器要能够生成HTTP GET报文,表单的发送生成POST报文等等。
    (2) 能够对各种的RESPONSE进行处理。
    (3)渲染Html文档,生成文档树,能够解释css,还要有个javascript引擎。
    (4)能够发起dns查询得到ip地址。
    浏览器是个非常复杂的软件,当然现在的浏览器对http协议的支持应该不是问题,它们主要纠结于html文档渲染部分,对于用户层出不穷的新需求,w3c层出不穷的新标准,浏览器的路应该才刚刚开始。 
    3, 服务器
    服务器有两个层级的概念,它可以是机器,它上面存着一个站点的所有东西,也可以是软件,安装在一个也叫做服务器的机器上,帮助这个机器分发用户想要的东西。 我对服务器研究不多,只是用过几次apache。所以只是简单的谈谈我的认识。
    服务器最基本的功能就是响应客户端的资源请求。服务器首先会侦听80端口,来了http请求,就根据请求进行处理,请求一个图片那就根据路径找到资源发回,请求静态html页面也是如此,如果请求的是像php这样的动态页面应该先调用php编译器(或是解释器吧)生成html代码,然后返回给客户端。当然还要解决的一个问题就是并行问题以应对大访问量。
    因为对这方面不太了解,只想到了这么多。

    先说到这里, 有了新的认识再写。


    来源:http://www.cnblogs.com/orchid/archive/2012/04/21/2461442.html

     

     

    来源:从输入网址到显示网页的全过程分析
    http://www.itmian4.com/forum.php?mod=viewthread&tid=1655&fromuid=1931

    展开全文
  • 浏览器输入网址后,首先浏览器需要知道访问的目标地址(也就是IP地址),如果,输入的是IP地址(如:172.217.24.14),那就跳过这一步了。 如果是字符串域名,先去DNS域名服务器查询对应域...
  • 浏览器多倍速播放视频,按检查或者按F12,console中输入: document.querySelector('video').playbackRate = 1.5 即为1.5倍速播放,欲多倍速播放,修改参数即可。
  • 输入网址浏览器渲染页面的过程

    千次阅读 2018-07-31 08:00:47
    1) 客户端浏览器输入网址URL。 2) 发送到DNS(域名服务器)获得域名对应的WEB服务器的IP地址。 3) 客户端浏览器与WEB服务器建立TCP(传输控制协议)连接。 4) 客户端浏览器向对应IP地址的WEB服务器发送相应的...
  • 其实安装方法也很简单,就只是安装管家10的方法多了一小步。 去官网下载一个安装包 和 改包名为 PCManager_Setup_10.1.2.33(C233) 其余步骤和工具网盘里。 感谢论坛用户提供的工具!!! 度盘:...
  • 1,确保手机和你的电脑处于一个局域网内 2,记得windows防火墙内打开相应的端口号。比如你的javaweb项目是tomcat运行的,...使用win+R键打开命令行窗口然后输入ipconfig查找最下的ipv4号就是你电脑上的ip地址...
  • 启动火狐浏览器后,地址栏输入地址时,当光标点中地址,浏览器页面卡了,等会整个页面就变灰了。 ![图片说明](https://img-ask.csdn.net/upload/201510/30/1446186931_522.png) 请大牛指点,不胜感激! ...
  • 作为一个软件开发者,你一定会对网络应用如何工作有一个完整的层次化的认知...1. 首先嘛,你得在浏览器输入网址: 2. 浏览器查找域名的IP地址 导航的第一步是通过访问的域名找出其IP地址。DNS查找过程如下:
  • 用Chrome在电脑上模拟微信浏览器

    千次阅读 2019-03-10 18:04:37
    用Chrome在电脑上模拟微信浏览器了解安卓微信和Ios微信的UA(User agent:用户代理)设置Chrome参数 了解安卓微信和Ios微信的UA(User agent:用户代理) 安卓微信UA:mozilla/5.0 (linux; u; android 4.1.2; zh-cn;...
  • 电脑浏览器模拟手机浏览器

    千次阅读 2013-07-08 20:14:18
    最近开发手机网站,需要测试不同的手机,比较麻烦,所以想到了用电脑浏览器来模拟手机浏览. 网上找了些资料,些方便有需要的朋友。 1.用谷歌Chrome浏览器:  Windows的【开始】-->【运行】中输入以下命令,...
  • 前言:前天看到曹大『caoz的梦呓』帅张『stormzhang』的星球说到一个经典面试题:从浏览器地址栏输入网址,到网页彻底打开,中间经历了什么。 结合曹大给的分析和自己查阅相关资料。遂整理出了这篇详细的文章供...
  • 浏览器可以访问到,但是手机就有时会出现FileNotFoundException,重点是把程序退出之后,有时又可以访问到该地址了请各位大侠帮帮忙![图片说明](https://img-ask.csdn.net/upload/201511/06/1446776052_575473.png...
  • 当我们开始在浏览器输入网址www.baidu.com的时候,浏览器其实就已经智能的匹配可能的url 了,他会从历史记录,书签等地方,找到已经输入的字符串可能对应的 url,然后给出智能提示,让你可以补全url地址。...
  • 当你键盘按下‘g’ 接下来的几节会解释所有有关键盘输入和操作系统中断的东西。但是之后发生的一大堆的事情是没有解释的。当你只是按下了’g’这个键,浏览器就会接收到这个事件,接下来浏览器的自动完成机制就...
  • 最近学习莫凡的Python的TensorFlow视频教程,学习到Tensorboard 可视化好帮手 1这一节时,执行 tensorboard --logdir logs之后遇到的浏览器输入http://localhost:6006 网址打不开的问题。 视频教程链接如下:...
  • 现如今当我们想要获取一些资料,首先是打开某个浏览器地址栏输入地址,想要的信息出现你的面前。 大家有没有想过输入地址就能返回给你想要的信息是怎么实现的呢? 下面就来简单说下它的实现流程,不过这之前...
  • IIS发布的webservice其他电脑上浏览器上没有参数输入框。 web.config的中间加入如下配置节内容              webservice 测试窗体只能用于来自本地计算机的请求,也是这个原因引起...
  • 电脑安装不chrome浏览器

    千次阅读 2018-11-25 17:23:40
    电脑安装不chrome浏览器 电脑谷歌浏览器卸载之后再也装不了,或者把chrome的一些文件删除了,整个浏览器都没法打开, 决定重装下,但是连卸载的功能都打不开了, 上网重新下载了个安装包,点了半天没有一点反应...
  • 2019独角兽企业重金招聘Python工程师标准>>> ...支付宝浏览器 就是自定义的ua 里面加上 AlipayClient 刷新页面就自动带了 转载于:https://my.oschina.net/shunshun/blog/1806722
  • 我打算我自己的window 10电脑上打开 查看。一开始是 防火墙没关。导致无法连接。 然后。我 我的电脑 或者 网络 那个选项里输入 那个远程 ip 地址。。确实打开了。但是总是自动打开浏览器。通过浏览器打开的。如...
  • Linux 浏览器无法输入中文解决办法

    万次阅读 2018-06-02 16:01:18
    当我们安装了centos系统后,系统默认安装了 ibus-libpinyin 输入法,此时Terminal终端中可以输入中文,但在浏览器中却只能输入英文,切换成中文输入法也不起作用,此时可按照下面的方法进行处理。 打开 /root/....
  • vs F5 后网站运行 ,手机浏览器输入什么 才能访问电脑网站 手机和电脑 是同一个 wifi的
  • 浏览器输入网址之后发生了什么 一、DNS域名解析 域名系统(英文:Domain Name System,缩写:DNS) 1、浏览器自己的DNS缓存中找,没有就下一步 2、操作系统的DNS缓存中找 3、操作系统本地自己的host文件中找 4、...
  • 1、ES浏览器访问电脑共享文件夹,访问不到,这是权限的问题。 2、修改权限

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 151,009
精华内容 60,403
关键字:

如何在电脑浏览器上输入网址