Skip to content

八股

约 2844 字大约 9 分钟

八股前端

2025-06-15

  1. 命名冲实 后绑定的重名数据系把前面的覆盖
  2. 安全风险 任何人可以获取和修改。
  3. 性能问题, 占用的存如果不解绑也不会清除
  4. 全局污染 任何人都可以获取到也可以修改

解决:模块化、命名空间、IIFE、开启严格模式、qiankun代理沙箱

地址栏输入url回车后发生了什么

1. url检测:纠错、补全、转换

检测url是否有误 如果没有带协议会补全协议 根据协议补全端口(http:80,https:443) 如果不是网址,是个关键词会使用搜索引擎加上关键词在搜索引擎中搜索 如果url中有中文等非ascii字符的话还会转换为ascii码

2. DNS解析

根据url地址先查看本地dns缓存,如果缓存命中则直接访问网址 如果缓存不命中则进行dns解析

3. 建立tcp连接

如果使用的是https协议还会再进行SSL握手,建立加密信道。使用SSL握手时,会确定是否使用了http2

4. 浏览器自动发送请求

浏览器决定要附带哪些cookie到请求头中 浏览器自动设置好请求头、协议版本、cookie,发出GET请求

5. 服务器处理数据并响应

服务器处理请求,进入后端处理流程。完成处理后,服务器响应一个HTTP报文给浏览器。

6. 浏览器决定是否保留连接

浏览器根据使用的协议版本,以及Connection字段的约定,决定是否要保留TCP连接

如果不需要保留会进行tcp四次挥手

7. 解析状态

根据响应状态码决定如何处理该请求

8. 解析响应头

浏览器根据响应头中的Content-Type字段识别响应类型,比如:html、css、js、图片等资源会做不同的处理

接着会根据请求头中的设置的缓存、cookie等做处理

9. 解析响应体

浏览器开始从上到下解析响应体的内容 如:解析HTML,若遇到外部资源链接,则进一步请求资源

10. 浏览器渲染过程

参照浏览器渲染原理

CSRF攻击

CSRF (Cross-site request forgery,跨站请求伪造) 攻击者利用了用户的身份信息,执行了用户非本意的操作

用户在请求正常的网站时会获取到cookie并保存在本地,后续再次请求该网站就把对应网站的cookie携带过去。 危险网站中的某个资源的链接(不用js执行请求是因为有跨域问题)指向要攻击的网站的请求以及设置请求头中携带的参数(因为是get请求只能使用请求头传参)。用户访问到危险网址时页面渲染到该元素就会发送请求,访问要攻击的网站,而在访问的时候用户本地存有cookie就会携带用户的cookie,而服务器就会误以为是用户在操作

防御方式

  1. 不使用cookie 防御力高,兼容性略差。ssr会遇到困难,但可解决

  2. 使用sameSite 防御力较高。兼容性差。容易挡住自己人

即使将敏感操作使用post请求也还是可以攻击到: 在页面中放一个表单,表单中填入网站和参数,使用表单也是可以发送post请求的。但是这样会跳转到目标页面,用户会看到,可以使用iframe标签包裹,这样只会在iframe标签中跳转,将iframe标签设为不可见用户就看不到了

sameSite是一个请求头的字段,该字段有三个取值:

  • none:无作用
  • sameSite-Strict:严格模式,只有源网站和请求的网址都一致(和cookie所属的网站一致)才会携带cookie。但这样会阻挡其他正常网站的访问
  • sameSite-Lax:只有get请求才会携带cookie,post请求不会携带cookie
  1. csrf token 防御力高,获取到token后未进行操作仍然会被攻击

用户请求服务器时,服务器会生成一个随机的token发送给用户(只有通过自己的网站访问才会使用这个token),且该token只能使用一次,并将该token保存在服务器上。当用户进行操作时会携带该token。如果不是自己的网站会使用保存的token就无法通过验证。使用后这个token就失效了

但用户获取到一次性toeken后再次发送请求还没有到达服务器,而在这期间又访问了危险网址,危险网站的请求先自己的请求到达服务器就也无法成功防护

  1. referer防护 防御力低,过去很常用,现在已经发现漏洞

请求头中携带referer字段(和origin字段很像都保存请求的源网站),如果referer的源网址不在服务器的白名单内就拒绝访问

但是将恶意代码使用base64编码后可以绕过

XSS攻击

XSS(Cross Site Scripting,跨站脚本攻击),攻击者利用站点的漏洞,表单提交 时,在表单内容中加入一些恶意脚本,当其他正常用户浏览页面,而页面中刚好出现攻击者的恶意脚本时,脚本被执行,从而使得页面遭到破坏,或者用户信息被窃取。 攻击者在正常的网址中发布所有人都可以访问的内容,如:文章。在写文章时在里面加入script等危险的标签,并在里面设置脚本代码。将该文件提交给服务器,服务器保存下来。正常用户访问时就会将这些内容发送给用户,用户浏览器渲染时就会将script标签中包裹的脚本执行

防御方式

服务器端对用户提交的内容进行过滤或编码

  • 过滤:去掉一些危险的标签,去掉一些危险的属性 由于前端如果过滤的话还有可能被篡改,或者发送未经过滤的标签,所以还需要后端处理。与其处理两次不如直接让后端处理
  • 编码:标签进行HTML实体编码
<srcipt>...</script>

编码后浏览器就不会识别成srcipt标签了,而是直接当成文本展现

网络性能优化

  • 优化打包体积 利用一些工具压缩、混淆最终打包代码,减少包体积
  • 多目标打包 利用一些打包插件,针对不同的浏览器打包出不同的兼容性版本,这样一来,每个版本中的兼容性代码就会大大减少,从而减少包体积
  • 压缩 现代浏览器普遍支持压缩格式,因此服务端的各种文件可以压缩后再响应给客户端,只要解压时间小于优化的传输时间,压缩就是可行的
  • CDN 利用CDN可以大幅缩减静态资源的访问时间,特别是对于公共库的访问,可以使用知名的CDN资源,这样可以实现跨越站点的缓存
  • 缓存 对于除HTML外的所有静态资源均可以开启协商缓存,利用构建工具打包产生的文件hash值来置换缓存
  • http2 开启http2后,利用其多路复用、头部压缩等特点,充分利用带宽传递大量的文件数据
  • 雪碧图 对于不使用HTTP2的场景,可以将多个图片合并为雪碧图,以达到减少文件的目的
  • defer、async 通过defer和async属性,可以让页面尽早加载js文件
  • prefetch、preload 通过prefetch属性,可以让页面在空闲时预先下载其他页面可能要用到的资源 通过preload属性,可以让页面预先下载本页面可能要用到的资源
  • 多个静态资源域 将相对独立的静态资源分到多个域中保存,可以让浏览器同时开启多个TCP连接,并行下载

WebSocket

短轮询

每隔一段时间就给服务器发送一下请求,服务器收到后响应结果 缺点:

  • 会产生大量无意义的请求
  • 会频打开关闭连接

长轮询

服务器收到请求后会先不响应,等一段时间后查看是否有结果,如果有结果就响应给客户端,客户端可能拿到结果。如果没结果就返回没有结果的响应,客户端收到后就会进行下一次轮询 长轮询有效的解决了话痨问题」,让每一次请求和响应都是有意义的

缺点:

  • 客户端长时间收不到购应会会导致超时,从而主动断开和服务器的连接 这种情况是可以处理的,但ajax请求因为超时而结束时,立即重新发送请求到服务器。虽然这种做法会让之前的请求变得无意义,但毕竟比短轮询好多了
  • 由于客户端可能「过早的」请求了服务器,服务器不得不挂起这个请求直到新消息的出现。这会让服务器长时间的占用资源却没什么实际的事情可做

WebSocket

WebSocket也是建立在TCP协议之上的,利用的是TCP全双工通信的能力 使用WebSocket,会经历两个阶段:握手阶段、通信阶段

虽然优于轮询方案,但WebSocket仍然是有缺点的:

  • 兼容性 WebSocket是HTML5新增的内容,因此古董版本的浏览器并不支持
  • 维持TCP连接需要耗费资源 对于那些消息量少的场景,维持TCP连接确实会造成资源的浪费

当客户端需要和服务器使用WebSocket进行通信时,首先会使用HTTP协议完成一次特殊的请求-响应,这一次请求-响应就是WebSocket握手

  1. 创建连接
let ws=new WebSocket('ws://localhost:8080')
  1. 设置回调函数
ws.onopen=()=>{
	// 连接成功触发
}

ws.onmessage=(e)=>{
	// 收到服务器的消息后触发
}

ws.onclose=()=>{
	// 连接关闭后触发
}
  1. 发送消息
ws.send('msg')

实例的readyState属性可以获取到连接状态

  • 0:正在连接
  • 1:已连接
  • 2:正在关闭
  • 3:已关闭

npm安装机制

  1. npm会检查本地的node_modules目录中是否已经安装过该模块,如果已经安装,则不再重新安装
  2. npm检查缓存中是否有相同的模块,如果有,直接从缓存中读取安装
  3. 如果本地和缓存中均不存在,npm会从registry指定的地址下载安装包,然后将其写入到本地的node_modules目录中,同时缓存起来。

贡献者

PinkDopeyBug

公告

本博客内容原本使用obsidian编写,由于没有仔细配置,以至图片引用使用obsidian风格。

且图片存储路径频繁变更导致部分文章图片无法正常显示。

为您带来不便请谅解。

ps:贡献者一直都只有wynnsimon一人,显示Pink的贡献者是因为我没好好配置git。后面因为懒就没一个个修改。如果被提及的人不希望被显示可以联系我我会立即删除。