序列号 | 内容 | 链接 |
---|---|---|
1 | 前端知识面试题 - http&https(2022版) | https://blog.csdn.net/qq_43061290/article/details/126651783 |
2 | 前端知识面试题 - 浏览器(2022版) | https://blog.csdn.net/qq_43061290/article/details/126776538 |
3 | 前端知识面试题 - HTML && CSS(2022版) | https://blog.csdn.net/qq_43061290/article/details/126776849 |
4.1 | 前端知识面试题 - JavaScript(2022版) | https://blog.csdn.net/qq_43061290/article/details/126845296 |
4.2 | 前端知识面试题 - JavaScript(2022版) | https://blog.csdn.net/qq_43061290/article/details/126863862 |
5 | 前端知识面试题 - TypeScript (2022版) | https://blog.csdn.net/qq_43061290/article/details/126985012 |
6.1 | 前端知识面试题 - Vue&&VueJs(2022版) | https://blog.csdn.net/qq_43061290/article/details/127021227 |
6.2 | 前端知识面试题 - Vue&&VueJs(2022版) | https://blog.csdn.net/qq_43061290/article/details/127021289 |
7 | 前端知识面试题 - React(2022版) | https://blog.csdn.net/qq_43061290/article/details/126690239 |
8 | 前端知识面试题 - nodeJs(2022版) | https://blog.csdn.net/qq_43061290/article/details/127140848 |
9 | 前端知识面试题 - Augluar(2022版) | https://blog.csdn.net/qq_43061290/article/details/127191959 |
10 | 前端知识面试题 - 模块化开发(2022版) | https://blog.csdn.net/qq_43061290/article/details/127023897 |
11 | 前端知识面试题 - 前端工程化(2022版) | https://blog.csdn.net/qq_43061290/article/details/127452051 |
12 | 前端知识面试题 - 性能优化(2022版) | https://blog.csdn.net/qq_43061290/article/details/127519309 |
13 | 前端知识面试题 - 大厂面试系列(2022版) | … |
http: 是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的超文本传输协议。
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。客户端向服务器发送一个请求报文,服务器以一个状态行作为响应。
• 1.客户端连接到Web服务器
• 2.发送HTTP请求
• 3.服务器接受请求并返回HTTP响应
• 4.释放TCP连接
• 5.客户端(浏览器)解析HTML内容
请求报文{ 请求行、请求头、空行、请求体 } 请求行:{http方法、页面地址、http协议、http版本} 响应报文{ 状态行、响应头、空行、响应体 }
https:是以安全为目标的 HTTP 通道,即 HTTP 下 加入 SSL 层进行加密。
https 协议的作用:建立一个信息安全通道,来确保数据的传输,确保网站的真实性。
• http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。
• Https 协议需要 ca 证书,费用较高。
• 使用不同的链接方式,端口也不同,一般,http 协议的端口为 80,https 的端口为 443。
• http 的连接很简单,是无状态的。
记忆口诀:明文传输超文本,安全等级各不同。CA证书费用高,无状连接端难同。
• HTTPS 协议要比 http 协议安全,可防止数据在传输过程中被窃取、改变,确保数据的完整性。
• https 握手阶段比较费时,会使页面加载时间延长 50%,增加 10%~20%的耗电。
• https 缓存不如 http 高效,会增加数据开销。
• SSL 证书也需要钱,功能越强大的证书费用越高。
• SSL 证书需要绑定 IP,不能再同一个 ip 上绑定多个域名,ipv4 资源支持不了这种消耗。
TCP/IP模型是互联网的基础,它是一系列网络协议的总称。这些协议可以划分为四层,分别为链路层、网络层、传输层和应用层
。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。
相同点:
不同点:
• 1xx:指示信息类,表示请求已接受,继续处理
• 2xx:指示成功类,表示请求已成功接受
• 3xx:指示重定向,表示要完成请求必须进行更近一步的操作
• 4xx:指示客户端错误,请求有语法错误或请求无法实现
• 5xx:指示服务器错误,服务器未能实现合法的请求
• 200 OK:客户端请求成功
• 301 Moved Permanently:所请求的页面已经永久重定向至新的URL
• 302 Found:所请求的页面已经临时重定向至新的URL
• 304 Not Modified 未修改。
• 403 Forbidden:对请求页面的访问被禁止
• 404 Not Found:请求资源不存在
• 500 Internal Server Error:服务器发生不可预期的错误原来缓冲的文档还可以继续使用
• 503 Server Unavailable:请求未完成,服务器临时过载或宕机,一段时间后可恢复正常
• 1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态码
o 100 - 继续 请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分
o 101 - 切换协议 请求者已要求服务器切换协议,服务器已确认并准备切换
• 2xx(成功)表示成功处理了请求的状态码
o 200 - 成功 服务器已经成功处理了请求。通常,这表示服务器提供了请求的网页
o 201 - 已创建 请求成功并且服务器创建了新的资源
o 202 - 已接受 服务器已接受请求,但尚未处理
o 203 - 非授权信息 服务器已经成功处理了请求,但返回的信息可能来自另一来源
o 204 - 无内容 服务器成功处理了请求,但没有返回任何内容
o 205 - 重置内容 服务器成功处理了请求,但没有返回任何内容
• 3xx(重定向)表示要完成请求,需要进一步操作;通常,这些状态代码用来重定向
o 300 - 多种选择 针对请求,服务器可执行多种操作。服务器可根据请求者(user agent)选择一项操作,或提供操作列表供请求者选择
o 301 - 永久移动 请求的网页已永久移动到新位置。服务器返回此响应(对GET或HEAD请求的响应)时,会自动将请求者转到新位置
o 302 - 临时移动 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求
o 303 - 查看其它位置 请求者应当对不同的位置使用单独的GET请求来检索响应时,服务器返回此代码
o 304 - 未修改 自上次请求后,请求的网页未修改过。服务器返回此响应,不会返回网页的内容
o 305 - 使用代理 请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理
o 307 - 临时性重定向 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有的位置来进行以后的请求
• 4xx(请求错误)这些状态码表示请求可能出错,妨碍了服务器的处理
o 400 - 错误请求 服务器不理解请求的语法
o 401 - 未授权 请求要求身份验证。对于需要登录的网页,服务器可能返回此响应
o 403 - 禁止 服务器拒绝请求
o 404 - 未找到 服务器找不到请求的网页
o 405 - 方法禁用 禁用请求中指定的方法
o 406 - 不接受 无法使用请求的内容特性响应请求的网页
o 407 - 需要代理授权 此状态码与401(未授权)类似,但指定请求者应当授权使用代理
o 408 - 请求超时 服务器等候请求时发生超时
o 410 - 已删除 如果请求的资源已永久删除,服务器就会返回此响应
o 413 - 请求实体过大 服务器无法处理请求,因为请求实体过大,超出了服务器的处理能力
o 414 - 请求的URI过长 请求的URI(通常为网址)过长,服务器无法处理
• 5xx(服务器错误)这些状态码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错
o 500 - 服务器内部错误 服务器遇到错误,无法完成请求
o 501 - 尚未实施 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码
o 502 - 错误网关 服务器作为网关或代理,从上游服务器无法收到无效响应
o 503 - 服务器不可用 服务器目前无法使用(由于超载或者停机维护)。通常,这只是暂时状态
o 504 - 网关超时 服务器作为网关代理,但是没有及时从上游服务器收到请求
o 505 - HTTP版本不受支持 服务器不支持请求中所用的HTTP协议版本
浏览器与服务器通信的方式为应答模式,即是:浏览器发起HTTP请求 – 服务器响应该请求。那么浏览器第一次向服务器发起该请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存中,简单的过程如下图:
由上图我们可以知道:
传送门 ☞ # 彻底理解浏览器的缓存机制
跨域的原理
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的。跨域访问是被各大浏览器所默认禁止的。
同源策略,是浏览器对 JavaScript 实施的安全限制,只要协议、域名、端口有任何一个不同,都被当作是不同的域。
跨域原理,即是通过各种方式,避开浏览器的安全限制。
解决方案
最初做项目的时候,使用的是jsonp,但存在一些问题,使用get请求不安全,携带数据较小,后来也用过iframe,但只有主域相同才行,也是存在些问题,后来通过了解和学习发现使用代理和proxy代理配合起来使用比较方便,就引导后台按这种方式做下服务器配置,在开发中使用proxy,在服务器上使用nginx代理,这样开发过程中彼此都方便,效率也高;现在h5新特性还有 windows.postMessage()
JSONP:
ajax 请求受同源策略影响,不允许进行跨域请求,而 script 标签 src 属性中的链 接却可以访问跨域的 js 脚本,利用这个特性,服务端不再返回 JSON 格式的数据,而是 返回一段调用某个函数的 js 代码,在 src 中进行了调用,这样实现了跨域。
步骤:
1. 去创建一个script标签
2. script的src属性设置接口地址
3. 接口参数,必须要带一个自定义函数名,要不然后台无法返回数据
4. 通过定义函数名去接受返回的数据
//动态创建 script
var script = document.createElement('script');
// 设置回调函数
function getData(data) {
console.log(data);
}
//设置 script 的 src 属性,并设置请求地址
script.src = 'http://localhost:3000/?callback=getData';
// 让 script 生效
document.body.appendChild(script);
JSONP 的缺点:
JSON 只支持 get,因为 script 标签只能使用 get 请求; JSONP 需要后端配合返回指定格式的数据。
预检
但是还有复杂一点的请求,我们需要先发OPTIONS请求,a.com想请求b.com它需要发一个自定义的Headers:X-ABC和content-type,这个时候就不是简单请求了, a.com要给b.com 发一个options请求,它其实在问b.com我用post行不行,还想在Headers中带X-ABC和content-type;并不是所有的headers都发这个OPTIONS请求,因为X-ABC是自定义的,所以需要发;b.com看到OPTIONS请求,先不会返回数据,先检查自己的策略,看看能不能支持这次请求,如果支持就返回200。
OPTIONS请求返回以下报文
HTTP/2.0 20 OK
Access-Control-Allow-Origin:https://a.com
Access-Control-Allow-Methods:POST,GET,OPTIONS
Access-Control-Allow-Headers:X-ABC,Content-Type
Access-Control-Max-Age:86400 // 告诉浏览器这个策略生效时间为一个小时,在一个小时之内发送类似的请求,不用在问服务端了,相当于缓存了
浏览器收到了OPTIONS的返回,会在发一次,这一次才是真正的请求数据,这次headers会带上X-ABC、contentType。
整体的过程cors将请求分为2种,简单请求和复杂请求,需不需要发送OPTIONS浏览器说的算,浏览器判断是简单请求还是复杂请求,cors是非常广泛的跨域手段 这里的缺点是OPTIONS请求也是一次请求,消耗带宽,真正的请求也会延迟。
跨域传送门 ☞ # 跨域,不可不知的基础概念
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
粘包出现原因
简单得说,在流传输中出现,UDP不会出现粘包,因为它有消息边界
粘包情况有两种,一种是粘在一起的包都是完整的数据包
,另一种情况是粘在一起的包有不完整的包
。
为了避免粘包
现象,可采取以下几种措施:
(1)对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令push,TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;
(2)对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;
(3)由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。分包多发。
以上提到的三种措施,都有其不足之处。
(1)第一种编程设置方法虽然可以避免发送方引起的粘包,但它关闭了优化算法,降低了网络发送效率,影响应用程序的性能,一般不建议使用。
(2)第二种方法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较高时,或由于网络突发可能使某个时间段数据包到达接收方较快,接收方还是有可能来不及接收,从而导致粘包。
(3)第三种方法虽然避免了粘包,但应用程序的效率较低,对实时应用的场合不适合。
一种比较周全的对策是:接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开。实验证明这种方法是高效可行的。
实现原理:
ajax 轮询指客户端每间隔一段时间向服务端发起请求,保持数据的同步。实现原理:
实现原理:
实现原理:
优点
:缺点:
建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
1、服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
2、客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。
为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
3、连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。
而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
简介:
特点:
算法强度复杂,安全性依赖于算法与密钥。
加密解密速度慢。
与对称加密算法的对比:
对称加密只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。
非对称加密有两种密钥,其中一个是公开的。
RSA应用场景:
由于RSA算法的加密解密速度要比对称算法速度慢很多,在实际应用中,通常采取
数据本身的加密和解密使用对称加密算法(AES)。 用RSA算法加密并传输对称算法所需的密钥。
HTTP/2 相比于 HTTP/1.1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,虽如此但HTTP/2并非完美的,HTTP/3 就是为了解决 HTTP/2 所存在的一些问题而被推出来的。
高延迟 — 队头阻塞(Head-Of-Line Blocking)
队头阻塞是指当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。
针对队头阻塞的解决办法:
无状态特性 — 阻碍交互
无状态是指协议对于连接状态没有记忆能力。纯净的 HTTP 是没有 cookie 等机制的,每一个连接都是一个新的连接。
Header里携带的内容过大,在一定程度上增加了传输的成本。且请求响应报文里有大量字段值都是重复的。
明文传输 — 不安全性
HTTP/1.1在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,无法保证数据的安全性。
不支持服务端推送
记忆口诀:队头阻塞高延迟,无状态阻交互,明文传输不安全,服务推送不支持。
HTTP 1.1多个文件共用一个TCP,这样可以减少tcp握手,这样3个文件就不用握手9次了,不过这样请求文件需要排队,请求和返回都需要排队, 如果第一个文件响应慢,会阻塞后面的文件,这样就产生了对头的等待问题。
有的网站可能会有很多文件,浏览器处于对机器性能的考虑,它不可能让你无限制的发请求建连接,因为建立连接需要占用资源,浏览器不想把用户的网络资源都占用了,所以浏览器最多会建立6个tcp连接;如果有上百个文件可能都需要排队,http2.0正在解决这个问题。
HTTP/2是现行HTTP协议(HTTP/1.x)的替代,但它不是重写。HTTP/2基于SPDY,专注于性能,最大的一个目标是在用户和网站间只用一个连接(connection) 。
1、二进制传输
HTTP/2传输数据量的大幅减少,主要有两个原因:以二进制方式传输和Header 压缩。我们先来介绍二进制传输,HTTP/2 采用二进制格式传输数据,而非HTTP/1.x 里纯文本形式的报文 ,二进制协议解析起来更高效。HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。
2、Header 压缩
HTTP/2并没有使用传统的压缩算法,而是开发了专门的"HPACK”算法,在客户端和服务器两端建立“字典”,用索引号表示重复的字符串,还采用哈夫曼编码来压缩整数和字符串,可以达到50%~90%的高压缩率。
3、多路复用
在 HTTP/2 中引入了多路复用的技术。多路复用很好的解决了浏览器限制同一个域名下的请求数量的问题,同时也更容易实现全速传输。
4、Server Push
HTTP2还在一定程度上改变了传统的“请求-应答”工作模式,服务器不再是完全被动地响应请求,也可以新建“流”主动向客户端发送消息。减少等待的延迟,这被称为"服务器推送"( Server Push,也叫 Cache push)
5、提高安全性
出于兼容的考虑,HTTP/2延续了HTTP/1的“明文”特点,可以像以前一样使用明文传输数据,不强制使用加密通信,不过格式还是二进制,只是不需要解密。
但由于HTTPS已经是大势所趋,而且主流的浏览器Chrome、Firefox等都公开宣布只支持加密的HTTP/2,所以“事实上”的HTTP/2是加密的。也就是说,互联网上通常所能见到的HTTP/2都是使用"https”协议名,跑在TLS上面。HTTP/2协议定义了两个字符串标识符:“h2"表示加密的HTTP/2,“h2c”表示明文的HTTP/2。
6、防止对头阻塞
http1.1如果第一个文件阻塞,第二个文件也就阻塞了。
http2.0的解决,把3个请求打包成一个小块发送过去,即使第一个阻塞了,后面2个也可以回来;相当于3个文件同时请求,就看谁先回来谁后回来,阻塞的可能就后回来,对带宽的利用是最高的;但没有解决TCP的对头阻塞,如果TCP发过去的一个分包发丢了,他会重新发一次;http2.0的解决了大文件的阻塞。
一个分包请求3个文件,即使第一个阻塞了,第二个也能返回
虽然 HTTP/2 解决了很多之前旧版本的问题,但它还是存在一个巨大的问题,主要是底层支撑的 TCP 协议造成的。HTTP/2的缺点主要有以下几点:
Google 在推SPDY的时候就搞了个基于 UDP 协议的“QUIC”协议,让HTTP跑在QUIC上而不是TCP上。而“HTTP over QUIC”就是HTTP/3,真正“完美”地解决了“队头阻塞”问题。
QUIC 虽然基于 UDP,但是在原本的基础上新增了很多功能,接下来我们重点介绍几个QUIC新功能。
QUIC基于UDP,而UDP是“无连接”的,根本就不需要“握手”和“挥手”,所以就比TCP来得快。此外QUIC也实现了可靠传输,保证数据一定能够抵达目的地。它还引入了类似HTTP/2的“流”和“多路复用”,单个“流"是有序的,可能会因为丢包而阻塞,但其他“流”不会受到影响。具体来说QUIC协议有以下特点:
XSS(Cross-Site Scripting,跨站脚本攻击)是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当被攻击者登陆网站时就会执行这些恶意代码,这些脚本可以读取 cookie,session tokens,或者其它敏感的网站信息,对用户进行钓鱼欺诈,甚至发起蠕虫攻击等。
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
DDoS又叫分布式拒绝服务,全称 Distributed Denial of Service,其原理就是利用大量的请求造成资源过载,导致服务不可用。
同源策略
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略来对脚本和请求进行校验,若不同源,则禁止使用。
同源的定义
那如果判断是否同源?主要根据三个维度,域名,协议,端口三个都相同才算同源。
举个 :
网站A网站B结果http://www.zhenai.com
|| http://i.z.com不同源,域名不同http://www.zhenai.com
|| http://www.z.cn不同源,域名不同http://www.zhenai.com
|| https://www.z.com不同源,协议不同http://www.zhenai.com
|| http://www.z.com:3000不同源,端口不同(默认端口80)
同源策略的作用
①无法用js读取非同源的Cookie、LocalStorage 和 IndexDB
这个主要是为了防止恶意网站通过js获取用户其他网站的cookie等用户信息。
②无法用js获取非同源的DOM
防止恶意网站通过iframe获取页面dom,从而窃取页面的信息。
③无法用js发送非同源的AJAX请求
防止恶意的请求攻击服务器窃取数据信息。
那是不是说非同源的请求就无法实现呢?也不是,这就引出了我们本文主要阐述的解决跨域请求问题的方法。
jsonp
jsonp能实现跨域是利用了img、script和link标签自身的跨域能力。
我们知道当img或者script中的src是一个链接的时候,浏览器会请求这个链接获取资源,那么这个链接如果是跨域的,浏览器也会请求,从而达到了跨域请求的一个功能。
用法
var script = document.createElement('script');
script.src = 'http://localhost:3000/api/test.do?a=1&b=2&callback=cb';
$('body').append(script);
function cb(res){
// do something
console.log(res)
}
可以看到,我们创建一个script标签,将src改成我们要请求的接口,并将script添加在body中,那么当浏览器解析到这个script时,会想src对应的服务器发送一个get请求,并将参数带过去。
然后当浏览器接收到服务端返回的数据,就会触发参数中callbak对应的回调函数cb,从而完成整个get请求。
优点
简单粗暴
缺点
①只支持get请求
②需要后台配合,将返回结果包装成callback(res)的形式
防范
那如果黑客植入script脚本通过jsonp的方式对服务器进行攻击,怎么办?
可以通过页面设置的内容安全协议csp进行防范。
cors跨域
cors 是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing),它允许浏览器向跨源服务器发送XMLHttpRequest请求,从而克服了 AJAX 只能同源使用的限制
cors 需要浏览器和服务器同时支持,整个 CORS通信过程,都是浏览器自动完成不需要用户参与,对于开发者来说,cors的代码和正常的 ajax 没有什么差别,浏览器一旦发现跨域请求,就会添加一些附加的头信息
但是,cors不支持ie10及以下版本。
简单请求和复杂请求
浏览器将cors请求分为简单请求和复杂请求。
简单请求则直接发送请求到服务器,只请求一次。
而复杂请求在正式请求前都会有预检请求,在浏览器中都能看到有OPTIONS请求,用于向服务器请求权限信息的,需要请求两次。
那如何区分是简单请求还是复杂请求呢?
简单请求
简单请求必须要同时满足下面三个条件:
content-type的类型
类型描述application/json消息主体是序列化后的 JSON 字符串application/x-www-form-urlencoded数据被编码为键值对。这是标准的编码格式multipart/form-data需要在表单中进行文件上传时,就需要使用该格式。常见的媒体格式是上传文件之时使用的text/plain数据以纯文本形式(text/json/xml/html)进行编码,其中不含任何控件或格式字符
application/json:
application/x-www-form-urlencoded:是Jquery的Ajax请求默认方式
复杂请求
不满足简单请求的条件,那么就是复杂请求。
复杂请求会在正式请求发送之前,先发一个预检请求进行校验,校验通过后才能进行正式请求。
举个
浏览器现在要发送一个put的复杂请求,那么在put请求发送之前,浏览器先发送一个options请求。
options请求头信息:
OPTIONS /cors HTTP/1.1
Origin: localhost:3000
Access-Control-Request-Method: PUT // 表示使用的什么HTTP请求方法
Access-Control-Request-Headers: X-Custom-Header // 表示浏览器发送的自定义字段
Host: localhost:3000
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
User-Agent: Mozilla/5.0...
服务器收到options请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应
options响应头信息
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://localhost:3000 // 表示http://localhost:3000可以访问数据
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
当options请求通过之后发出正式的HTTP请求,倘若options请求不通过,则服务器不允许此次访问,从而抛出错误
options请求通过之后的,浏览器发出发请求
PUT /cors HTTP/1.1
Origin: http://api.zhenai.com
Host: api.alice.com
X-Custom-Header: value
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
options请求缓存
那这样的话,如果页面存在大量的复杂请求,岂不是每个请求前面都要进行一次options的请求,那不会造成大量资源的浪费么?
如果基于cors请求的方法来解决跨域问题,那么复杂请求之前是需要进行一个options的请求的,但我们可以通过对options请求进行缓存来减轻请求的压力。
在options请求中,我们可以通过设置响应头的参数Access-Control-Max-Age来对结果进行缓存
比如: Access-Control-Max-Age: 600 表示对options检验结果进行十分钟的缓存
nginx
nginx解决跨域的问题跟之前的方法有所不同,它是通过服务器的方向代理,将前端访问域名跟后端服务域名映射到同源的地址下,从而实现前端服务和后端服务的同源,那自然不存在跨域的问题了。
举个 :
前端服务:http://localhost:3000,
前端页面路由:http://localhost:3000/page.html,
后端服务:http://localhost:3001,
后端接口路由:http://localhost:3001/api/test.do
可以看出,两个服务处于跨域的状态
通过nginx的配置进行反向代理,即可实现前后端服务同源,如下:
server
{
listen 80;
server_name localhost;
location = / {
proxy_pass http://localhost:3000;
}
location /api {
proxy_pass http://localhost:3001;
#指定允许跨域的方法,*代表所有
add_header Access-Control-Allow-Methods *;
#预检命令的缓存,如果不缓存每次会发送两次请求
add_header Access-Control-Max-Age 3600;
#带cookie请求需要加上这个字段,并设置为true
add_header Access-Control-Allow-Credentials true;
#表示允许这个域跨域调用(客户端发送请求的域名和端口)
#$http_origin动态获取请求客户端请求的域 不用*的原因是带cookie的请求不支持*号
add_header Access-Control-Allow-Origin $http_origin;
#表示请求头的字段 动态获取
add_header Access-Control-Allow-Headers
$http_access_control_request_headers;
#OPTIONS预检命令,预检命令通过时才发送请求
#检查请求的类型是不是预检命令
if ($request_method = OPTIONS){
return 200;
}
}
}
其实nginx不仅仅只是用于解决跨域问题,而是涉及到很多服务器资源分配的处理,在此就不详细探讨了。
vue proxyTable
其实,在我们主流使用的MVVM框架中,配置项里面也提供解决跨域问题的能力,继续举个 ,以vue2.x为例,我们可以通过在config/index.js中添加配置项实现跨域请求:
proxyTable: {
'/apis': {
// 测试环境
target: 'http://www.zhenai.com/', // 接口域名
changeOrigin: true, //是否跨域
pathRewrite: {
'^/apis': '' //需要rewrite重写的,
}
}
}
原理
其实原理很简单,就是在我们使用npm run dev命中,启动了一个node服务,然后将前端发出的请求发送到node服务,再将该服务转发到原本的后台服务,在这过程中实现了一层代理,由一个node服务发送一个请求到另外一个后台服务,自然也没有了浏览器所限制的跨域问题。
结束语
面对经济的下行和大学生毕业人数的突增,现在的就业状况极其严峻。所以,很多小伙伴转行到计算机行业。但是,到计算机行业就真的能够就业吗?很多培训机构宣传的培训方向就适合自己吗?就培训方向做一下自己的小分析,不喜互喷!哈哈哈
1 Java:大多数的培训机构都会有这个选择,但是这个真的很卷,大厂每年都有一批很优秀的985211去投递。
2 大数据:这个方向需要一个大公司,适合有高学历、数学极好的人。一个小公司是没有数据可言的,进去基本就是Java开发!门槛很高
3 前端:这个方向其实是很缺的。因为好的前端开发,都去阿里了!适合逻辑不强的人。
最后,感谢微莱羽墨、小泽今天早睡、里见HU和牛客黑太帅等多位老师的创作!!!
!此专题 后期会不定时修改、更新
。