身为前端从业人员,HTML、CSS、JS固然是我们赖以生存的三叉戟,但是不能忽视的一点是我们所搭建的网页是要依靠浏览器来运行的,因此了解掌握一定的网络知识将会让我们手中的利器更加所向披靡。
我们从那个被说烂的话题开始:我们在浏览器里输入一个地址到页面完整呈现,这其中究竟发生了些什么(我们这篇只说前半部分)?
DNS解析
每一台计算机都有一个唯一的IP地址,计算机根据IP实现相互通信,而我们通常使用的域名更多的是为了方便记忆以及个性化需要,它并不能直接对应到的服务器IP,我们需要经过DNS服务器去查找IP,这个根据域名找到IP地址的过程就是DNS解析。
网络协议
通过DNS解析拿到IP地址后我们就根据IP地址和默认端口与服务器进行TCP
连接,这里根据协议不同端口号也有区别,HTTP协议是80
,HTTPS协议是443
,它们之间的区别我们稍后说,先来说说TCP
。
计算机网络共有七层协议:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
TCP
协议位于传输层,用于提供应用进程之间的逻辑通信。通过TCP
三次握手过程确保和服务器已经建立连接后浏览器就可以向其发送HTTP请求了。
HTTP请求
HTTP位于应用层,它是构建在TCP/IP协议上的,它的请求报文由四个部分组成:请求行、请求头、空行、请求体。
请求行
请求行中包括了请求方法(常用POST、GET)、请求URL(不包括域名)以及HTTP协议版本。例如:
GET /a.html HTTP/1.1
请求头
请求头包括了很多属性:
属性名 | 含义 |
---|---|
User-Agent |
产生请求的浏览器类型 |
Accept |
客户端希望接受的数据类型,比如 Accept:text/xml(application/json)表示希望接受到的是xml(json)类型 |
Authorization |
用于表示HTTP协议中需要认证资源的认证信息 |
Cookie |
客户端通过这个头可以向服务器带数据,这是最重要的请求头信息之一,改变了HTTP的无状态性,可以保存用户状态 |
Content-Type |
发送端发送的实体数据的数据类型。比如,Content-Type:text/html(application/json)表示发送的是html(json)类型 |
Cache-Control |
用来指定当前的请求是否使用缓存机制,常见的取值有public、private、no-cache、max-age、must-revalidate |
Host |
请求的主机名,允许多个域名同处一个IP地址,即虚拟主机 |
Referer |
表示这个请求是从哪个URL过来的 |
空行用于告知服务器请求头已结束。
请求体
当进行POST请求时会有请求体。
HTTPS协议
由于HTTP协议是以明文的方式来发送内容,不提供任何方式的数据加密,因此很容易受到攻击导致信息被截取。而HTTPS协议是在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密,安全性会更高。
HTTP 2.0
HTTP 2.0是1999年HTTP/1.1发布后的下一代HTTP协议,在开放互联网上HTTP 2.0将只用于https://网址,而http://网址将继续使用HTTP/1。
相比 HTTP/1.x,HTTP 2.0有很多新特性:
1、二进制分帧层:HTTP 2.0增加了一个二进制分帧层,改进了传输性能,实现了低延迟和高吞吐量。
2、压缩头部:对请求头进行了压缩,相同的请求不会在头部带上未改变的属性。
3、多路复用:可以连接发起多重的请求,HTTP1中的keep-alive用于长连接而不必重新建立连接,然而keep-alive必须等本次请求彻底完成后才能发送下一个请求,而HTTP2的请求与响应以二进制帧的形式交错进行,大大提高了效率。
4、请求优先:可以对资源的下载顺序进行排序。
5、服务端推送:可以将资源主动推送给客户端。
HTTP响应
服务器接收到请求后会对其进行处理并返回HTTP报文,响应报文也由四个部分组成:状态行、响应头、空行、响应体。
状态码
状态行格式如下:HTTP-Version Status-Code Reason-Phrase。
其中,HTTP-Version
表示服务器HTTP协议的版本;Status-Code
表示服务器发回的响应状态代码;Reason-Phrase
表示状态代码的文本描述。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
1xx
:指示信息–表示请求已接收,继续处理。2xx
:成功–表示请求已被成功接收、理解、接受。3xx
:重定向–要完成请求必须进行更进一步的操作。4xx
:客户端错误–请求有语法错误或请求无法实现。5xx
:服务器端错误–服务器未能实现合法的请求。
比较常见的状态码有:
状态码 | 状态描述 |
---|---|
200 (OK) |
请求成功 |
301 (Moved Permanently) |
永久重定向。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
304 (Not Modified) |
自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容 |
400 (Bad Request) |
客户端请求的语法错误,服务器无法理解,通常是请求参数有误 |
401 (Unauthorized) |
表示发送的请求需要有HTTP认证信息或者是认证失败了 |
403 (Forbidden) |
服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 (Not Found) |
服务器无法根据客户端的请求找到资源 |
500 (Internal Server Error) |
服务器内部错误,无法完成请求 |
响应头
响应头用于描述服务器的基本信息,以及数据的描述,服务器通过这些数据的描述信息,可以通知客户端如何处理等一会儿它回送的数据。
常用的响应头信息:
属性 | 描述 |
---|---|
Allow |
服务器支持哪些请求方法(如GET、POST等) |
Content-Encoding |
文档的编码(Encode)方法 |
Content-Type |
表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType |
Date |
当前的GMT时间 |
Expires |
告诉浏览器把回送的资源缓存多长时间,-1或0则是不缓存 |
Etag |
指示资源的状态唯一标识 |
Last-Modified |
文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置 |
Refresh |
表示浏览器应该在多少时间之后刷新文档 |
Server |
服务器名字 |
Set-Cookie |
设置和页面关联的Cookie |
WWW-Authenticate |
表示在请求获取这个实体时应当使用的认证模式 |
响应体
响应体就是响应的消息体,如果是纯数据就是返回纯数据,如果请求的是HTML页面,那么返回的就是HTML代码,如果是JS就是JS代码等等。
缓存机制
浏览器在向服务器请求资源时并不一定每一次都从服务器重新获取,因为浏览器自身的缓存机制可以帮助我们处理从何处获取资源的问题。
通过Cache-Control
指定缓存机制,当第一次请求资源时,http响应头会包含以下信息:
Last-Modified
——资源最后修改的时间Etag
——资源的状态唯一标识Expires
——资源在浏览器缓存中的过期时间
然后浏览器会将文件缓存到Cache
目录下,并同时保存文件的上述信息。当第二次请求该文件时,浏览器会先检查Cache
目录下是否含有该文件,如果有,并且还没到Expires
设置的时间,即文件还没有过期,那么此时浏览器将直接从Cache
目录中读取文件,而不再发送请求。如果文件此时已经过期,则浏览器会发送一次HTTP请求到服务器,并在头部携带上当前文件的如下信息:
If-Modified-Since Thu, 26 Nov 2009 13:50:19 GMT
If-None-Match “8fb8b-14-4794674acdcc0”
也就是把文件上一次修改的时间,以及上一次请求返回的Etag
值一起发送给服务器。服务器在接收到这个请求的时候,先解析Header里头的信息,然后校验该头部信息。如果该文件从上次时间到现在都没有过修改或者Etag
信息没有变化,则服务端将直接返回一个304
的状态,而不再返回文件资源。如果服务器经过匹配发现文件修改过了,就会将文件资源返回,并带上新文件状态信息。
通过这种缓存机制就可以很大程度减少网络带宽优化网络性能,这对于提升用户体验也是一个极大的帮助。