想起以前挺多公司的面试都有要求会网络知识点的,而且今天前端的微信公众号就有推,搬运过来记一记。 原文链接:https://mp.weixin.qq.com/s/J9bU6HuD94dw7o-M6hEq7g
一、HTTP协议
1、什么是TCP/IP协议
不同的硬件、操作系统之间进行通信,需要一种规则,我们把这种规则称做协议,网络传输的各个阶段有不同的协议,这些协议的集合总称为TCP/IP协议。http协议是TCP/IP协议的子集。
2、TCP/IP分层及各层的作用?
分为四层:应用层、传输层、网络层、链路层。
应用层:http协议属于这一层,在这一层根据http协议生成针对目标服务器的http请求报文,服务器端根据http解析报文。
传输层:TCP协议属于这一层,在这一层将根据TCP协议将http的请求报文分割成报文段,在服务器端会根据TCP协议合并报文段。建立和断开TCP连接的过程就是三次握手,四次挥手。
网络层:IP协议属于这一层,网络层的作用是确定数据传输的路线。根据IP协议搜索对方地址,并一边中转一边传送。IP地址指明了节点被分配的地址,MAC地址是网卡所属的固定地址,IP地址可以变,MAC一般不变。整个中转的过程像是送快递,用户把数据送到快递站,快递公司再送到一个个大型中转站。
链路层:网络传输过程中的硬件部分。
过程:客户端发出请求->应用层发送http请求报文->传输层建立TCP连接,将报文分成报文段->网络层根据请求的ip地址,进行处理并加上MAC地址后交给链路层->链路层将数据送到请求的ip地址->请求ip的服务器根据IP,TCP,HTTP协议对数据进行拼接等处理->服务器收到请求。
3、DNS是什么?
DNS是和http一样位于应用层的协议,用于解析域名,DNS协议提供通过域名查找IP地址或者IP地址反查域名的服务。
4、URI和URL的区别
URI是统一资源标识符,URL是统一资源定位符,URL是URI的子集。
URI格式:协议名/方案名+登录信息(可选)+服务器地址(网址或ip)+端口号(可选)+文件路径+参数(可选)+片段标识符(可选,哈希值)
两者区别就就是URL是确定了文件的路径,而URI只是唯一的标识出文件,但是不一定是该文件的路径。
5、什么是持久连接?
如果一个请求就建立一次TCP连接,那么过程太费时间,资源,效率低下。所以,持久化连接就是三次握手建立TCP连接后,一直保持连接,直到四次挥手,才断开连接。
6、什么是管线化?
因为持久连接,所以不必等一个请求响应后再发起下一个请求,可以同时发送多个请求。大大节省了时间。
7、cookie的诞生原因?
http协议是无状态的,不会保存之前一切请求的报文信息,所以假设有一个网站需要登录,用户登录之后,在之后的访问过程中怎么保持登录状态,就成为一个问题。解决方法就是引入cookie技术。
8、关于cookie的知识
cookie是为了用户识别和状态管理,web网站为了管理用户状态,会把一些数据临时写入用户的计算机内,当用户访问该网站时,可取回之前存放的cookie。
1) cookie是不可跨域的,每个域名下的cookie是单独保存的,不会混用。在一个页面下发送的请求,带的都是当前域名下的cookie。
2) cookie的重要属性
name:cookie的名字,同域名下name不能相同,否则会被覆盖
value:cookie的值
path:路由
secure:打钩时,只会在https等安全协议下传输这个cookie
HttpOnly:打钩时,则不能通过js获取,防止xss攻击
Expires/Max-age:cookie有效期,当为session时,关闭浏览器(非页面)就会清除。
若为过期时间,则到时间时浏览器自动删除。
复制代码
3) 服务端一旦通过set-cookie将cookie存储到客户端,就没有方法可以直接删除,而只能通过覆盖的方式删除。
9、状态码
状态码分为5大类:
1XX:信息状态类
2XX:成功类
3XX:重定向类
4XX:客户端错误类
5XX:服务端错误类
复制代码
不能完全相信状态码,有时候返回的状态码和实际情况是不一致的!!
200:正常处理
301:永久重定向,浏览器自动再次发送新的请求
302:临时重定向,浏览器自动再次发送新的请求
303:与302相似,但表示客户端应该采用get方法获取新的资源,浏览器自动再次发送新的请求
304:附带条件未满足,和重定向没有关系,服务器可通过此状态码高速客户端,使用本地缓存
403:服务端拒绝了请求,但没有给具体原因
404:服务器上没有请求的资源
500:服务器在执行的时候发生了错误
503:服务器超负载或停机维护
复制代码
10、一台服务器多个域名,IP地址一样,怎么区分
利用虚拟主机的技术,可以实现一台物理服务器上,部署多个域名,但是用DNS服务解析多个域名的时候,解析成的ip地址是一样的,那怎么区分请求的是哪个资源呢?
利用请求头里的host字段来指定主机名或者是域名的URI,host一般只是发送域名,而referer则是完整的url地址,origin则是跨域的时候发送的。
11、代理服务器
代理服务器:接收客户端请求,转发给其他服务器,代理服务器根据两个维度,可分为缓存代理,非缓存代理。透明代理和非透明代理(对数据进行处理)。
12、常用报文头部字段
cache-control:控制缓存的行为
connection:管理连接,keep-alive持久连接
cookie:
set-cookie:设置cookie
referer:当前请求的原始页面
cache-control:控制浏览器缓存
Last-Modified:最后一次更新时间
if-Modified-Since
Etag
If-None-Match
复制代码
13、get和post的区别
get和post是http协议中规定的,告知服务器意图的方法。使用get方法用来请求已被URI识别的资源,而post方法用来传输实体主体,但get请求也可以发送实体,post请求也可以在url上加参数。本质上,两者都是TCP连接,区别是get发送一次数据包,post发送两次数据包。
在表面上,get和post的区别如下:
1、关于传入参数的大小限制,http协议里没有规定,只不过是浏览器和服务器的约定俗称。
2、关于传递参数的安全性,get请求的url是在服务器上有日志记录,在浏览器也能查到历史记录,但是post请求的参数都在body里面,服务器日志记录不到,浏览器历史也记录不到,所以相对来说安全些。
3、get请求可以缓存,post请求不能缓存
14、localstorage、sessionstorage、cookie
window.localStorage/sessionStorage.setItem("key", "value")
window.localStorage/sessionStorage.getItem("key")
window.localStorage/sessionStorage.removeItem("key")
复制代码
15、http的缺点,https如何保证安全?
1、通信不加密,可能被窃听
2、不验证通信方身份,可能有伪装情况
3、无法证明报文的完整性。可能被篡改
SSL和TLS协议解决了以上的缺点,让http更加安全
SSL/TLS协议和http协议组合,就是https。https实际上就是披着SSL/TLS的http协议。
https并不是直接通过非对称加密传输过程,而是有握手过程,握手过程主要是和服务器做通讯,生成私有秘钥,最后通过该秘钥对称加密传输数据。还有验证证书的正确性。证书验证过程保证了对方是合法的,并且中间人无法通过伪造证书方式进行攻击,HTTPS 相对于 HTTP 性能上差点,因为多了 SSL/TLS 的几次握手和加密解密的运算处理,但是加密解密的运算处理已经可以通过特有的硬件来加速处理。
16、三次握手,四次挥手
1、何为三次握手
在建立TCP连接的时候,客户端和服务端一共要发送三次报文,才会成功的建立连接。客户端->服务端->客户端。
2、为什么需要三次握手,而不是两次
如果出现以下场景:客户端发出去的第一个连接请求由于某些原因在网络节点中滞留了导致延迟,直到连接释放的某个时间点才到达服务端,这是一个早已失效的报文,但是此时服务端仍然认为这是客户端的建立连接请求第一次握手,于是服务端回应了客户端,此时如果仅有两次握手的话,连接就建立了,这肯定是浪费资源的行为。
为什么不是四次或更多次握手呢?因为每一次握手都是耗费时间和资源的事,四次握手或者更多次当然也是可以的,但考虑到成本,三次就够了。
3、何为四次挥手
当要断开TCP连接时,客户端或服务器均可主动发起挥手动作,发起方发起一个报文,表明我不再发起数据了,但是我还可以接收数据。接收方可能也有消息要继续发送,所以接收方分两次发送给发起方,一次报文是可以带着数据,还有一次是表示关闭TCP,发起方接收到这两个报文后,回复给接收方,TCP链接中断。
为什么不是一次,两次,三次,五次?原理其实和三次握手类似的。
17、从输入网址到显示网页,经过哪些步骤
1、浏览器查询域名对应的IP地址
2、获取到IP地址后,就开始建立客户端和服务器的TCP连接,首先判断是不是https的,如果是,则HTTPS其实是HTTP + SSL / TLS 两部分组成,也就是在HTTP上又加了一层处理加密信息的模块。HTTP协议是三次握手的过程,https协议则在三次握手的基础上还有SSL握手过程。
3、建立好TCP连接后,开始发送HTTP请求。
4、服务端处理后,返回HTTP响应。
5、当http响应返回完毕后,TCP并没有断开,HTTP/1.1 中,Connection: keep-alive 是默认启用的,表示持久连接。在反向代理软件 Nginx 中,持久连接超时时间默认值为 75 秒,如果75秒内没有新到达的请求,则断开与客户端的连接。同时,浏览器每隔 45 秒会向服务器发送 TCP keep-alive 探测包,来判断 TCP 连接状况,如果没有收到 ACK 应答,则主动断开与服务器的连接。
6、断开TCP连接,四次挥手。
7、浏览器渲染页面
二、缓存
1、与缓存相关的报文头部
Expires:服务端返回的数据到期时间,时间是 GMT 格式的标准时间,如 Fri, 01 Jan 1990 00:00:00 GMT。
Cache-Control:有很多属性,不同的属性代表的意义也不同。
private:客户端可以缓存
public:客户端和代理服务器都可以缓存
max-age=t:缓存内容将在t秒后失效
no-cache:需要使用协商缓存来验证缓存数据
no-store:所有内容都不会缓存。
Cache-Contro优先级高于Expires
Last-Modified:资源最近修改时间,由服务器告诉浏览器。
if-Modified-Since:从xxx时间开始,是否被修改过,由浏览器告诉服务器。
if-Unmodified-Since:从xxx时间开始,是否没有被修改过,由浏览器告诉服务器。
Etag:资源标识,由服务器告诉浏览器。
If-None-Match:缓存资源标识,由浏览器告诉服务器。
Etag和If-None-Match的作用:
复制代码
2、Last-Modified和Etag的作用和区别
通过If-None-Match请求头带上了之前服务端返回的Etag的值。服务端收到第二次请求的时候,发现携带了If-None-Match字段,就重新计算服务器对应资源的Etag,如果二者匹配了,就认为资源没有发生变化,直接给客户端相应304,让客户端读取缓存中的数据
Last-Modified先出现,但是在使用过程中发现了一个问题:有时候,资源虽然更新了,但是最后更新时间没有改变,导致客户端获取不到最新的数据。所以后来发明了Etag,直接来判断文件是否有变化。
3、缓存的过程
1、浏览器请求 a.js。
2、服务器返回 a.js,同时告诉浏览器过期绝对时间(Expires)以及相对时间(Cache-Control:max-age=10),以及a.js上次修改时间Last-Modified,以及 a.js 的Etag。
3、Cache-Contro优先级高于Expires。10秒内浏览器再次请求 a.js,不再请求服务器,直接使用本地缓存。
4、11秒时,浏览器再次请求 a.js,请求服务器,报文中带上 If-Modified-Since(对应Last-Modified) 和 If-None-Match(对应Etag)。
5、服务器收到浏览器的If-Modified-Since和If-None-Match,发现有If-None-Match,则比较 If-None-Match 和 a.js 的 Etag 值,忽略If-Modified-Since的比较。
6、a.js 文件内容没变化,则Etag和If-None-Match 一致,服务器告诉浏览器继续使用本地缓存(304)。如此往复。
三、网络安全
1、前端常见的攻击 XSS、CSRF
XSS攻击的原理是,攻击者通过注入某些代码,来执行某些恶意操作。
比如,用户再输入框里输入一些html的代码,网页展示的时候,网页本身的代码和用户输入的html代码混在一起,导致浏览器执行了用户输入的恶意代码。
1、所有用户输入的地方都不安全
2、所有展示用户输入的地方都不安全
3、js 里不要用 eval
4、不要用 innerHTML
CSRF攻击的原理是,攻击者构造网站后台某个功能接口的请求地址,诱导用户去点击或者用特殊方法让该请求地址自动加载。用户在登录状态下这个请求被服务端接收后会被误以为是用户合法的操作。
四、跨域
1、什么是跨域
前端通常说的跨域是指狭义的跨域,是指因为浏览器同源策略引起的一种限制访问场景。
2、什么是同源策略
浏览器为了安全(防止XSS等攻击),浏览器会限制从脚本内发起的跨源HTTP请求。跨源即不同协议、域名(子域不同也不行)、端口。
浏览器并不是拒绝所有的跨域请求,通常浏览器允许进行跨域写操作和资源嵌入操作,如链接,重定向,img、css、script标签。
而不允许通过脚本发起的跨域操作:如ajax或fetch请求,并且浏览器会限制不同源的Cookie、LocalStorage的读取;不同源的DOM 和 JS 对象也无法获取。
3、为什么我们需要跨域的需求
工程服务化后,不同职责的服务分散在不同的工程中,往往这些工程的域名是不同的,但一个需求可能需要对应到多个服务,这时便需要调用不同服务的接口,因此会出现跨域。
4、跨域的常用解决策略
1、jsonp
jsonp的核心就是利用script标签请求不同源的资源这一特性。而我们可以将我们想要的资源通过js代码的形式返回给我们,即返回一段js代码,是调用我们本地的一个函数,我们想要的数据通过参数传递过来,这样我们就可以在本地的函数里获取到这些数据了。 jsonp只支持GET请求
jq里jsonp的简单实现
function jsonp({url,jsonp,data,success,error}){
var _script = document.createElement('script')
var head = document.getElementsByTagName('head')[0]
window[jsonp]=function(arg){
head.removeChild(script)
if(arg.isSuccess==true){
success(arg)
}else{
error(arg)
}
window[jsonp]=null
}
_script.src=url+format(data)
head.appendChild(script)
function format(params){
let arr = []
for(let item in params){
arr.push(`${item}=params[item]`)
}
return arr.join('&')
}
}
复制代码
2、CORS
CORS(Cross-origin resource sharing)跨域资源共享,一种跨域技术,它使用额外的 HTTP 头来告诉浏览器 让Web应用被准许访问来自不同源服务器上的指定的资源。
所以,同源策略是浏览器的限制,而CORS技术就是通过一些http头部字段,让浏览器允许跨域!
跨域请求可以分为两种,浏览器针对这两种请求的处理方式是不一样的:
1)简单请求,满足以下所有条件:
– 请求方法是以下三种方法之一:GET、HEAD、POST
– 请求头的Content-Type 的值是下列三者之一:text/plain(纯文本)、multipart/form-data(表单数据)、application/x-www-form-urlencoded
跨域请求或者是post请求时,请求头中会包含Origin字段,它用于表示请求的来源页面,和referer的区别在于它没有路径,只有协议、域名和端口。服务器端收到简单请求后,会检测请求头中的Origin字段,如果服务器端判断可以访问,则在响应头中加入Access-Control-Allow-Origin字段。当其值为*或者时与Origin相同时,表示可以访问外域资源,浏览器就会把响应报文显示出来。否则会爆出一个错误。
2)复杂请求:满足以下任意条件:
– 使用了下面任一 HTTP 方法:PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH
– Content-Type 的值不属于下列之一:application/x-www-form-urlencoded、multipart/form-data、text/plain
– 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段,即头部字段超出了以下范围。该集合为:Accept、Accept-Language、Content-Language、Content-Type (需要注意额外的限制)、DPR、Downlink、Save-Data、Viewport-Width、Width
浏览器在检测到跨域请求为复杂请求时,就会自动先发送一次预检请求,该请求的方法为option方法,请求头部会包含两个字段:
Origin:http://foo.example
<!--用来告诉服务器,实际的请求将会采用什么方法-->
Access-Control-Request-Method:POST
<!--告知服务器,实际请求,头部会携带哪些自定义的字段-->
Access-Control-Request-Headers:X-PINGOTHER, Content-Type
复制代码
服务器则会判断是否允许请求。如果允许请求,返回的响应头中会包含以下字段:
// 允许来自http://foo.example的访问
Access-Control-Allow-Origin: http://foo.example
<!--允许的请求方法-->
Access-Control-Allow-Methods: POST, GET, OPTIONS
<!--允许的自定义头-->
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
<!--该响应的有效时间为 86400 秒,在有效时间内,浏览器无须为同一请求再次发起预检请求-->
Access-Control-Max-Age: 86400
复制代码
3)关于跨域时的cookie
将 XMLHttpRequest 的withCredentials标志设置为true,从而向服务器发送 Cookies。但是,服务端响应头必须包含Access-Control-Allow-Credentials: true,否则浏览器将不会将响应内容发送给请求者,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。
总结关于跨域的http字段:
请求头部字段:
Origin:<origin>
// 表明预检请求或实际请求的源站。
Access-Control-Request-Method:<method>
//将实际请求所使用的 HTTP 方法告诉服务器。
Access-Control-Request-Headers:<field-name>[, <field-name>]*
//将实际请求所携带的首部字段告诉服务器。
复制代码
响应头部字段:
Access-Control-Allow-Origin: <origin> | *
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
Access-Control-Max-Age: <delta-seconds>
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: <method>[, <method>]*
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
复制代码
五、CDN
1、基本原理
1、当用户点击网站页面上的内容URL,经过本地DNS系统解析,DNS系统会最终将域名的解析权交给CNAME指向的CDN专用DNS服务器。
2、CDN的DNS服务器将CDN的全局负载均衡设备IP地址返回用户。
3、用户向CDN的全局负载均衡设备发起内容URL访问请求。
4、CDN全局负载均衡设备根据用户IP地址,以及用户请求的内容URL,选择一台用户所属区域的区域负载均衡设备,告诉用户向这台设备发起请求。
5、区域负载均衡设备会为用户选择一台合适的缓存服务器提供服务,选择的依据包括:根据用户IP地址,判断哪一台服务器距用户最近;根据用户所请求的URL中携带的内容名称,判断哪一台服务器上有用户所需内容;查询各个服务器当前的负载情况,判断哪一台服务器尚有服务能力。基于以上这些条件的综合分析之后,区域负载均衡设备会向全局负载均衡设备返回一台缓存服务器的IP地址。
6、全局负载均衡设备把服务器的IP地址返回给用户。
7、用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传送到用户终端。如果这台缓存服务器上并没有用户想要的内容,而区域均衡设备依然将它分配给了用户,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉到本地。
2、总结
1、CDN的本质是缓存,而内核中支撑它的互联网精神则是共享
2、CDN的本质上是将媒体资源,动静态图片(Flash),HTML,CSS,JS等等内容缓存到距离你更近的IDC,从而让用户进行共享资源,实现缩减站点间的响应时间等等需求,而网游加速器的本质则是通过建立高带宽机房,架设多节点服务器来为用户进行加速。
六、其他
1、浏览器并发请求数量
浏览器对同一域名下的并发请求数量有限制,一般是6个左右,原因如下:
从前端角度:浏览器同时发出多个连接会导致浏览器不得不多开几个线程,而线程有时候算不得是轻量级资源,毕竟做一次上下文切换开销不小。
从后端角度:即使浏览器即使放弃保护自己,将所有请求一起发给服务器,也很可能会引发服务器的并发阈值控制而被BAN
2、为什么静态资源的域名和一般和数据接口的域名不一样
从cookie的角度考虑,如果静态资源和接口的域名用同一个,那么每次请求静态资源,都会把cookie带入,浪费了性能,所以,一般会用新的域名。
- 版权声明:本文基于《知识共享署名-相同方式共享 3.0 中国大陆许可协议》发布,转载请遵循本协议
- 文章链接:https://www.imiowo.com/661.html [复制] (转载时请注明本文出处及文章链接)
发表评论