简单的回答是:等待。当然这是从我们用户的角度来看。
从机器的角度, 这之间有着大量的任务要完成。而且随着技术的进步(HTTP/2, HTTPS,IPv6),互联网规模的增长(Load Balencer,CDN),和用户体验的需求的提高(快速,安全),这个任务列表也在不断演化,并会根据具体情况有很多变数。
最简单的流程
这个最简单的流程基于一些假设,比如这是第一次访问某网站;之使用当前主流又必须的技术,如简单的HTTP 1.1的GET请求, IPv4,没有代理,CDN之类。
- 用户输入URL(注意不是IP地址而是URL),如
http://www.hackingnote.com/index.html
。浏览器从URL中提取出域名(www.hackingnote.com
)。 - 浏览器并不能直接利用这个域名,它需要一个IP才能发送请求。浏览器会依次查找它自己,操作系统,路由,和ISP的缓存;如果未找到相应记录则进行一次DNS的搜索:当一个DNS服务器存有该域名的记录,相应的IP地址将被返回,否则转发给其他的DNS服务器。
- 浏览器最终得到了解析后的IP,并尝试用这个IP和服务器在三次握手后建立一个TCP连接
- 浏览器发送HTTP请求(request)
- 服务器接收到HTTP请求,找到所要求的资源,如HTML,并发送HTTP响应(response)
- 浏览器接收到HTTP响应,关闭TCP连接
- 浏览器查看响应的状态码,如果是401无权限,404无响应,则显示相应错误;301,302则跳转到其他页面(需要发送新的请求);200则解析并渲染相应中附带的HTML,呈现给用户。
HTTP/2
在HTTP 1.1中,每个request都需要建立一个TCP连接,得到响应后连接关闭。如果HTML中有大量的外部Javascript或css的文件,则每个文件都需要一个单独的请求。所以在HTTP 1.1时代的一个优化原则是,尽可能合并外部文件以减少请求数。但HTTP/2中TCP连接可以被保留,并且多个请求可以被并行发送。那条优化原则就不再适用了。
HTTPS
HTTP是明文传送的,如果请求中包含用户名和密码就会有很大的被截获的风险。如果试用HTTPS,则会在发送端和接受端都增加一个加密解密的过程。
CDN
如果使用CDN(Content Delivery Network),如AWS的CloundFront,或CloudFlare,网站的域名信息会被保存到CDN的Name Server中,用户不再直接访问网站的服务器,而是限访问最近的CDN的节点,如果缓存中存有所请求的页面会直接放回,否则CDN会发送请求到网站服务器,HTTP响应也是通过CDN最终发回浏览器。
动态网站和静态网站
如果只是从字面意思理解,很容易把这两者的区别想成一个可以有动态图片或视频,一个只能是静止的文字;也并非前者才能有代码执行而后者不能加有任何javascript。真正的区别在于对于同样的网址,所返回的内容是否是固定的。
对于静态网站,服务器在收到请求后,直接查看是否存在所请求的资源并发送响应。动态网站则复杂的多,通常需要从后台读取数据库,组装成所需要的HTML再返回。
拿博客举例:Ghost是动态网站(WordPress同理,只是把Node.js换成PHP),Nginx(或Apache)服务器作为反向代理,会将请求转发给Node.js,Node根据请求从数据库中提取内容,将生成的HTML返回Nginx,Nginx再发回浏览器。
而如果用Jekyll,Nanoc,或Hexo这类静态网站生成器,HTML会被预先生成好,当请求到达Nginx或Apache时,HTML会被直接提取并返回。