从输入网址到页面呈现的详细过程

面试题经典题目,简要回答如下:

a.域名解析

b.发起TCP连接的三次握手

c.建立TCP连接后发起http请求

d.服务端响应http请求,返回响应报文

e.浏览器页面渲染

f.断开TCP连接

下面详细介绍:

a.域名解析

DNS解析,当在浏览器中输入一个URL,如“www.baidu.com”时,这个地址并不是百度网站真正意义的地址。每一台连上网计算机都有一个唯一标识即它的IP地址,DNS解析就将输入的网址解析成IP地址。

DNS解析是一个递归查询的过程,例如要解析“www.baidu.com”时,过程如下:

在本地域名服务器中查询IP地址,未找到域名;

本地域名服务器会向根域名服务器发送请求,未找到域名;

本地域名服务器向.com顶级域名服务器发送请求,未找到域名;

本地域名服务器向.baidu.com域名服务器发送请求,找到该域名,将相应的IP返回给本地域名服务器;

b.发起TCP连接的三次握手

HTTP协议是使用TCP协议作为其传输层协议的,在拿到服务器的IP地址后,客户端浏览器会与服务器建立TCP连接,该过程包括三次握手:

第一次握手:建立连接时,客户端向服务端发送请求报文(SYN)

第二次握手:服务器收到请求报文后,如同意连接,则向客户端发送确认报文(SYN/ACK)

第三次握手:客户端收到服务器的确认后,再次向服务器发送确认报文,完成连接(ACK)

三次握手主要是为了防止已经失效的请求报文字段发送给服务器,浪费资源。

c.建立TCP连接后浏览器发起HTTP请求

浏览器构建HTTP请求报文,并通过TCP协议传送到服务器的指定端口。HTTP请求报文一共有三个部分:

  报文首部(请求行+各种首部字段+其他)

  空行(它的作用是通过一个空行,告诉服务器请求头部到此为止。)

  报文主体(应被发送的数据)通常并不一定要有报文主体

下面对百度首页的请求报文首部进行分析:

请求行

请求方法GET 请求URI /   HTTP协议版本 1.1
GET / HTTP/1.1    

首部字段(请求头)

请求资源所在服务器
Host: www.baidu.com
连接方式:持久连接     HTTP/1.1之前版本默认非持久连接
Connection: keep-alive
报文指令:要求所有中间服务器不返回缓存资源
Pragma: no-cache
控制缓存的行为:缓存前必须先确认其有效性,防止从缓存中返回过期的资源
Cache-Control: no-cache
用户代理可处理的媒体类型
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8   q表示权重从而区分优先级
http客户端浏览器信息
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
可接受的内容编码类型
Accept-Encoding: gzip, deflate, sdch
可接受的语言
Accept-Language: zh-CN,zh;q=0.8
相关信息或标记
Cookie: BAIDUID=3C67AA3EF6B3347D3AA986CE489268C4:FG=1; BIDUPSID=3C67AA3EF6B3347D3AA986CE489268C4;

常见的请求头字段含义:

Accept: 浏览器可接受的MIME类型。

Accept-Charset:浏览器可接受的字符集。

Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip。Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间。

Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。

Authorization:授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中。

Content-Length:表示请求消息正文的长度。

Host: 客户机通过这个头告诉服务器,想访问的主机名。Host头域指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回。

If-Modified-Since:客户机通过这个头告诉服务器,资源的缓存时间。只有当所请求的内容在指定的时间后又经过修改才返回它,否则返回304“Not Modified”应答。

Referer:客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的(防盗链)。包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。

User-Agent:User-Agent头域的内容包含发出请求的用户信息。浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用。

Cookie:客户机通过这个头可以向服务器带数据,这是最重要的请求头信息之一。

Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝。

From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它。

Connection:处理完这次请求后是否断开连接还是继续保持连接。如果Servlet看到这里的值为“Keep- Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入 ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。

Range:Range头域可以请求实体的一个或者多个子范围。例如,

表示头500个字节:bytes=0-499

表示第二个500字节:bytes=500-999

表示最后500个字节:bytes=-500

表示500字节以后的范围:bytes=500-

第一个和最后一个字节:bytes=0-0,-1

同时指定几个范围:bytes=500-600,601-999

但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200 (OK)。

UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和CPU类型。

HTTP请求报文格式如下

d.服务端响应http请求,返回响应报文

HTTP响应报文由四部分组成:响应行、响应头、空行、响应体

响应行

响应行一般由协议版本、状态码及其描述组成,比如

HTTP/1.1 200 OK

常见状态码

100~199:表示成功接收请求,要求客户端继续提交下一次请求才能完成完整的处理过程

200~299:表示成功接收请求并处理完成。常用200

300~399:为完成请求,客户需进一步细化请求,例如:请求的资源转移到一个新地址、常用302(转移请求),304和307(请求缓存)

400~499:客户端的请求有错误,常用404(web服务器中没有要请求的资源)和403(权限不够、服务器拒绝访问)

500~599:服务器端出现错误,常用500

响应头

响应头用于描述服务器的基本信息,以及数据的描述,服务器通过这些数据的描述信息,可以通知客户端如何处理等一会儿它回送的数据。

常见的响应头字段含义:

Allow:服务器支持哪些请求方法(如GET、POST等)。

Content-Encoding:文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE4、IE5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader(“Accept- Encoding”))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。

Content-Length:表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStram,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。

Content- Type:表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置 Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。

Date:当前的GMT时间,例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。

Expires:告诉浏览器把回送的资源缓存多长时间,-1或0则是不缓存。

Last-Modified:文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。

Location:这个头配合302状态码使用,用于重定向接收者到一个新URI地址。表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。

Refresh:告诉浏览器隔多久刷新一次,以秒计。

Server:服务器通过这个头告诉浏览器服务器的类型。Server响应头包含处理请求的原始服务器的软件信息。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。Servlet一般不设置这个值,而是由Web服务器自己设置。

Set-Cookie:设置和页面关联的Cookie。Servlet不应使用response.setHeader(“Set-Cookie”, …),而是应使用HttpServletResponse提供的专用方法addCookie。

Transfer-Encoding:告诉浏览器数据的传送格式。

WWW-Authenticate:客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader(“WWW-Authenticate”, “BASIC realm=”executives”“)。注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问。

注:设置应答头最常用的方法是HttpServletResponse的setHeader,该方法有两个参数,分别表示应答头的名字和值。和设置状态代码相似,设置应答头应该在发送任何文档内容之前进行。

setDateHeader方法和setIntHeader方法专门用来设置包含日期和整数值的应答头,前者避免了把Java时间转换为GMT时间字符串的麻烦,后者则避免了把整数转换为字符串的麻烦。

HttpServletResponse还提供了许多设置

setContentType:设置Content-Type头。大多数Servlet都要用到这个方法。

setContentLength:设置Content-Length头。对于支持持久HTTP连接的浏览器来说,这个函数是很有用的。

addCookie:设置一个Cookie(Servlet API中没有setCookie方法,因为应答往往包含多个Set-Cookie头)。

响应体

响应体就是响应的消息体,如果是纯数据就是返回纯数据,如果请求的是HTML页面,那么返回的就是HTML代码,如果是JS就是JS代码,如此之类。

HTTP响应报文格式如下

e.浏览器页面渲染

  解析文档构建DOM树

  构建渲染树

  布局和绘制渲染树

f.断开TCP连接

  第一次挥手:客户端想分手,发送消息(FIN)给服务器

  第二次挥手:服务器通知客户端已经接受的挥手请求,返回确认消息(ACK),但还没做好分手准备

  第三次挥手:服务器已经做好分手准备,通知客户端(FIN)

  第四次挥手:客户端发送消息给服务器(ACK),确认分手,服务器关闭连接。

原文地址:https://www.cnblogs.com/lhh520/p/10232738.html