每日八股-6.12
- 计算机网络
- 1.当我们在浏览器中输入一个 URL 并按下回车后,到页面最终显示出来,这中间都发生了哪些关键步骤?
- 2.请简述一下 JWT(JSON Web Tokens)的原理和校验机制
- 3.DNS 是如何进行域名解析的?它属于 OSI 哪一层的协议?
- 4.HTTP 协议定义了哪些常用的请求方法?你的项目中用了哪些?
- 5.HTTP 协议有哪些常见的状态码?你能说出一些你熟悉的吗?
- 6.HTTP 协议是长连接还是短连接呢?长连接的好处了解吗?
- 7.HTTP/1.0 和 HTTP/1.1 之间有哪些主要的区别?
- 8.Cookie、Session 和 Token 这三种技术有什么异同之处?它们分别适用于哪些场景?
- 9.什么是跨域?在什么情况下会发生跨域请求?
计算机网络
1.当我们在浏览器中输入一个 URL 并按下回车后,到页面最终显示出来,这中间都发生了哪些关键步骤?
首先,我们需要解析浏览器客户端的URL,因为网络传输需要ip地址,一个正确的URL包括协议,比如http,https,ftp;域名,比如www.baidu.com;端口,对于http来说,默认端口是80,对于https来说,默认端口是443;路径,比如说我们像访问百度贴吧里面某一个具体的帖子,那么后面一定会跟随一个具体的路径。
解析出这些之后,我们需要获得请求的ip地址,首先我们需要查看浏览器的缓存是否有这个ip地址,如果有直接返回,如果没有,我们接下来去查操作系统的缓存,比如hosts,看有没有ip地址,如果有,直接返回,如果没有,我们就要用到域名解析协议,也就是DNS,本地域名服务器会帮我们去递归的查询ip地址。首先,去查根域名服务器,然后去查顶级域名服务器,最后去查权威域名服务器,这样我们就得到了ip地址。
得到了ip地址之后,我们就可以与服务器建立TCP连接,如果使用的协议是http的话,那么我们用三次握手来建立TCP连接,具体细节是首先客户端发送一个SYN包到服务器,表示我要开始与你建立连接了,然后服务器返回一个SYN ACK包表示服务器收到了来自客户端的建立连接请求,之后客户端再发送一个ACK包表示收到了来自服务器的SYN ACK包,可以正式开始传输数据了。如果使用的协议是https的话,那么我们用四次握手来建立安全的TCP连接。
在完成了建立连接后,浏览器将之前的http报文逐层的向下传输并封装该层的特定信息,比如说到传输层就要封装上源端口和目的端口;到网络层就要封装上源ip和目的ip;到数据链路层就要封装上源mac地址和目的mac地址,另外,在数据链路层,我们会使用到ARP协议来广播请求,以此来知道下一跳的目标mac地址。
就这样,我们经过了无数个路由器最终到达了目的服务器,服务器通过与刚才相反的路径返回我们请求的资源,在浏览器web页面上渲染出来,呈现给用户。
2.请简述一下 JWT(JSON Web Tokens)的原理和校验机制
JWT的全称是JSON WEB TOKENS,是一种基于Json的开放标准,一个JWT由三个部分构成
-
头部(header)
头部包括两个字段,第一个字段是alg,也就是指明我们的加密算法,分为对称算法和非对称算法两种,对称算法用到的一般是HS256,非对称算法一般用到的是RS256;第二个字段是typ,这是一个固定值JWT,用来表示他是一个jwt token。头部会使用base64 url来进行编码,并进行加密
-
负载(payload)
负载主要存储的是实际信息,包括用户登录信息,过期时间等等,他也需要用base64 url来进行编码,但是他不会加密,所以说我们不能将任何敏感的数据存放在负载里。
-
签名(signature)
签名是服务器用来验证客户端传来的jwt的完整性和真实性,它等于alg(解密后的头部+“.”+解密后的负载+secret)
校验机制是这样的:客户端发来一个jwt token,服务器端用头部中的算法计算base64 url解密后的头部加上base64 url解密后的负载加上服务器端的密钥,看是否用jwt token中的签名一致,如果一致,说明没有被篡改,可以进行后续的操作。
补充Refresh Token
为什么需要Refresh Token?
- Access Token,即jwt,在客户端请求服务器时,会频繁的暴露在网络传输中,极有可能会被窃取,如果说jwt token设置的过期时间很长,那么对用户会造成损失
- 如果jwt token设置的过期时间很短,比如说15分钟,那么用户在使用服务的时候,每隔十五分钟就需要重新输入一次密码,这对于用户的体验感是极差的
所以说,我们在Access Token的基础上,引入了Refresh Token,它解决了上面两个问题,首先,Access Token通常存储在内存中,而Refresh Token一般存在cookie上,这保证了安全性,另外最重要的是我们引入Refresh Token来刷新Access Token的这一过程,对用户是无感的,也就是用户不会察觉到。
Access Token (访问令牌):就像是你酒店房间的房卡。它的有效期很短(比如 15 分钟到 1 小时),你每次进房间(访问受保护的 API)都需要出示它。它直接暴露给各种服务,风险较高。
Refresh Token (刷新令牌):就像是你办理入住时拿到的入住凭证。它的有效期很长(比如 7 天或 30 天),你平时都把它妥善保管起来,不会轻易示人。它的唯一作用就是,当你的房卡(Access Token)过期失效时,你可以拿着这个凭证去前台(特定的刷新接口),换一张新的房卡。
所以,Refresh Token 本身并不用于访问业务 API,它唯一的作用就是用来获取新的 Access Token。
3.DNS 是如何进行域名解析的?它属于 OSI 哪一层的协议?
DNS属于应用层的协议。
当我们在浏览器输入一个url后,浏览器首先检查自己的缓存,看有无对应的ip地址,有就直接返回,没有就去检查操作系统的缓存,如果还没有,本地域名服务器先检查自己的缓存,如果没有就去递归的搜寻ip,首先去根域名服务器,根域名服务器会告诉本地域名服务器去哪个顶级域名服务器找,然后去顶级域名服务器,顶级域名服务器会告诉本地域名服务器去哪个权威域名服务器找,最后到权威域名服务器找到需要的ip地址,并逐层向上返回。
这时本地域名服务器会将ip缓存下来,以便于下一次访问同样的url,浏览器和操作系统也可能将ip缓存下来。
4.HTTP 协议定义了哪些常用的请求方法?你的项目中用了哪些?
我了解到的有GET、PUT、POST、HEAD、DELETE请求。
GET请求用于从服务器获取资源, PUT请求用于将请求体中的内容更新到服务器上,POST请求用于往服务器添加资源,HEAD请求只会获取资源的头部信息,DELETE请求用于从服务器删除资源。
项目中用到的请求是GET和POST请求。
5.HTTP 协议有哪些常见的状态码?你能说出一些你熟悉的吗?
- 2开头的状态码,表示服务器已成功接收到请求,常见的有200 OK
- 3开头的状态码,表示客户端需要进一步的操作才能访问资源,通常是重定向,常见的比如301 Moved permanently,表示永久重定向
- 4开头的状态码,表示客户端错误,常见的比如说403 forbidden,表示服务器禁止访问该资源,404 not found,表示服务器找不到该资源
- 5开头的状态码,表示服务器错误,常见的比如说500 internal server error,表示服务器内部错误,502 bad gateway,表示服务器作为网关时,从后端服务器收到了无效响应
6.HTTP 协议是长连接还是短连接呢?长连接的好处了解吗?
这个要区分http/1.0和http/1.1
如果是http/1.0,默认的就是短链接,也就是说客户端完成了一次对服务器的请求,该连接就会关闭,除非显式在请求头中指定connection keep alive。
如果是http/1.1,默认的就是长连接,除非显式指定connection close,长连接的好处就是客户端要多次访问同一url时,不需要多次的建立连接,只需在第一次建立连接就可以,没有了多次建立和关闭连接的开销,提升了通信的效率和性能。
7.HTTP/1.0 和 HTTP/1.1 之间有哪些主要的区别?
- 最关键的一点,1.1默认长连接,1.0默认短链接,长连接可以减少频繁创建和关闭TCP连接的开销,提升网络通信性能和效率
- 1.1支持管道化请求传输,1.0只能等待一个请求返回响应之后,再传输下一个请求,但1.1可以在一个连接上发送多个请求,但需要保证返回响应的顺序,这会造成队头阻塞
队头阻塞:比如说连接上有三个请求,第一个请求要访问一个很大的数据文件,预估耗时3秒,第二个请求只需要访问一段文字,预计耗时0.01秒,第三个请求只要访问一张图片,预计耗时0.01秒,因为要保证返回响应的顺序性,即使我的后续请求只需要很短时间完成,那么也需要等待前面的请求先返回响应,这就是队头阻塞
- 1.1引入了更多的缓存控制,比如Entity Tag,If-Match等等
- 1.1针对带宽进行了优化,允许只访问服务器的部分资源,这可以保证用户在下载大文件的断点续传功能
- 1.1支持虚拟主机,通过引入host头部字段,可以明确指定要访问的域名;1.0的一大缺陷就是服务器只知道要访问的ip地址,但不知道具体的域名是什么,如果说一台服务器上托管了多个网站,服务器就无法区分请求是发给哪个网站的。
8.Cookie、Session 和 Token 这三种技术有什么异同之处?它们分别适用于哪些场景?
Cookie存储在客户端(浏览器),它主要用来存储一些非敏感的数据,比如说用户偏好等,安全性低,默认不支持跨域
Session存储在服务器端,服务器会为每一个发来请求的客户维护一个唯一的session ID,并通过cookie发给客户端,安全性较高,跨域的支持有限,可能需要一些特殊方法实现跨域
Token存储在客户端,它包含客户的一些登录信息和权限信息,服务器可以通过验证token来进行用户的登录和授权,token会使用算法加密,安全性高,且支持跨域
从适用场景来看,Cookie适用于存储一些临时数据,做简单的状态管理;Session适用于传统的web应用,需要保护用户的敏感信息;Token则适用于现代的web应用和Restful Api,尤其是需要跨域和无状态服务的场景。
9.什么是跨域?在什么情况下会发生跨域请求?
跨域指的是在浏览器环境下,去访问不同源的资源,这里的源包括域名,协议,端口。
以下场景都会发生跨域请求
- 当前协议是http,要去访问https下的资源
- 当前域名是example.com,要去访问example2.com的资源
- 当前端口是默认端口80,要去访问端口8080的资源
一个现实场景中的例子就是现在的前后端分离项目,前端应用部署在一个域名之下,而后端的api服务部署在另一个域名之下,当前端通过fetch发送请求,比如说获取用户列表或者提交表单数据,这时就发生了跨域请求,解决方案之一是后端服务器会在响应头中添加Access-Control-Allow-Origin: http://www.my-frontend-app.com(前端域名) 来允许前端域名访问。