1. Webpack的日常使用、配置
以下是一些常用的 Webpack 配置项:
entry(入口):指定项目的入口文件或多个入口文件。
output(输出):
path
:打包输出的路径。filename
:输出文件的名称。module(模块):
rules
:配置各种类型文件的处理规则和加载器。resolve(解析):
exensions
:自动解析确定的文件扩展名。alias
:模块路径别名。plugins(插件):添加各种功能的插件,如:
HtmlWebpackPlugin
:生成 HTML 文件并自动引入打包后的资源。CleanWebpackPlugin
:清理输出目录。devServer(开发服务器):
port
:开发服务器端口。hot
:开启热更新。optimization(优化):
splitChunks
:进行代码分割配置。mode(模式):可设置为
development
(开发模式)或production
(生产模式),会影响一些默认行为和插件的运行。module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'], }, ], }, resolve: { extensions: ['.js', '.json'], alias: { '@': path.resolve(__dirname,'src'), }, }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', }), ], devServer: { port: 8080, hot: true, }, mode: 'development', };
2. 常见Loader、Plugin
常见 Loader:
ts-loader
:用于处理 TypeScript 文件。vue-loader
:处理 Vue 单文件组件。json-loader
:加载 JSON 文件。raw-loader
:将文件以原始文本形式加载。常见 Plugin:
CommonsChunkPlugin
(在 Webpack 4 中有新的替代方案):提取公共模块。ProvidePlugin
:自动加载模块,为代码提供全局变量。ProgressPlugin
:显示打包进度。BannerPlugin
:在打包文件头部添加版权信息等横幅。IgnorePlugin
:忽略特定模块的引入。DllPlugin
和DllReferencePlugin
:用于构建和使用动态链接库,提升构建速度。CaseSensitivePathsPlugin
:确保文件路径大小写敏感。WebpackMd5HashPlugin
:计算打包文件的 MD5 哈希值。
3. 手写Webpack Plugin、Loader
去除 HTML 标签的 Webpack Plugin 示例代:
class StripHtmlTagsPlugin { constructor(options) { this.options = options || {}; } apply(compiler) { compiler.hooks.emit.tapAsync('StripHtmlTagsPlugin', (compilation, callback) => { for (const asset of Object.values(compilation.assets)) { if (asset.name.endsWith('.html')) { const htmlContent = asset.source().toString(); const strippedContent = htmlContent.replace(/<[^>]*>/g, ''); compilation.assets[asset.name] = { source: () => strippedContent, size: () => strippedContent.length, }; } } callback(); }); } } module.exports = StripHtmlTagsPlugin;
手写 Webpack Plugin 时,需要特别留意以下几个方面:
- Webpack 版本兼容性:不同版本的 Webpack 可能会对 Plugin 的接口和钩子的行为有所更改。确保您了解所针对的 Webpack 版本的特性和变化。
- 例如,在 Webpack 4 和 5 中,某些插件的钩子参数和行为可能有所不同。
- 钩子的正确使用:熟悉各种钩子的触发时机和参数含义,选择最合适的钩子来实现您的功能。比如,
compilation.hooks.buildModule
钩子在模块构建时触发,而compilation.hooks.chunkAsset
钩子在生成 chunk 相关的资源时触发。- 对资源的安全操作:在修改资源内容时,要注意不要意外破坏资源的结构或导致不可预期的结果。例如,如果不小心删除了重要的 HTML 标签或破坏了 CSS 的语法,可能会导致页面显示异常。
- 内存管理:避免在 Plugin 中造成内存泄漏。及时释放不再使用的资源和变量。比如,如果在 Plugin 中创建了大量的临时对象,但没有及时清理,可能会消耗过多内存。
- 错误处理的全面性:考虑到各种可能出现的错误情况,并进行恰当的错误处理和提示。例如,文件读取失败、网络请求出错等情况都应有相应的处理逻辑。
- 配置的灵活性:尽量使 Plugin 能够接受灵活的配置参数,以满足不同项目的需求。比如,一个压缩图片的 Plugin 可以接受压缩质量、尺寸限制等配置。
4. Webpack的构建流程
Webpack 的构建流程主要包括以下几个步骤:
初始化参数
- Webpack 首先会读取配置文件(通常是
webpack.config.js
)和命令行参数,获取构建的相关配置,例如入口文件路径、输出路径、加载器规则等。开始编译
- 根据入口文件的路径,Webpack 开始解析入口文件,并创建一个模块依赖图。
模块解析
对于每个模块(例如 JavaScript 文件、CSS 文件、图片等),Webpack 会使用对应的加载器(Loader)对其进行处理,将不同类型的模块转换为 JavaScript 模块。
例如,使用
css-loader
处理 CSS 文件,将其转换为可以在 JavaScript 中使用的模块。依赖收集
- 在解析模块的过程中,Webpack 会递归地收集模块的依赖关系,并将它们添加到模块依赖图中。
代码生成
- 根据模块依赖图,Webpack 生成最终的输出代码。
输出
- 将生成的代码输出到指定的输出目录中。
例如,如果我们有一个 Webpack 配置,指定了入口文件为
index.js
,并且在这个文件中引入了一个 CSS 文件style.css
。Webpack 会首先解析index.js
,发现对style.css
的依赖,然后使用相应的加载器处理style.css
,将处理后的结果和index.js
一起构建成最终的输出代码,并按照配置输出到指定的目录。再比如,如果项目中使用了 ES6 的模块语法,Webpack 能够正确地处理这些模块的依赖关系,确保在最终的输出中模块的加载顺序是正确的。
5. Webpack优化前端的手段
以下是 Webpack 用于优化前端的一些常见手段:
代码分割(Code Splitting):
- 可以将应用程序拆分成多个块(chunks),只在需要时加载特定的模块。例如,通过
splitChunks
配置,可以将常用的第三方库提取到单独的 chunk 中,避免重复加载。
- 例如,将
lodash
这样的大型库从业务代码中分离出来。压缩代码(Code Minification):
- 对 JavaScript、CSS 和 HTML 进行压缩,去除不必要的空格、注释和缩短变量名等,减小文件体积。
- 像
UglifyJSPlugin
用于压缩 JavaScript 代码。缓存策略(Caching Strategy):
- 利用
chunkhash
或contenthash
为输出的文件生成唯一的哈希值。当文件内容未改变时,浏览器可以直接使用缓存,提高加载速度。
- 例如,修改了一个模块,但未影响其他模块时,只有该模块对应的文件哈希值改变,其他未变的模块仍可使用缓存。
图片优化(Image Optimization):
- 使用合适的 loader 如
url-loader
和file-loader
对图片进行处理,例如压缩图片大小。Tree Shaking:
- 去除未使用的代码,只打包实际使用到的代码。这需要使用 ES6 的模块语法。
- 假设一个模块中有多个函数,但在项目中只使用了其中一个,Webpack 可以在打包时去除未使用的函数
懒加载(Lazy Loading):
- 实现页面模块的按需加载,提高初始加载速度。
- 比如,在用户点击某个按钮时,再加载对应的模块。
优化模块查找(Module Resolution Optimization):
- 合理配置
resolve
选项,减少模块查找时间。使用缓存加载器(Using Caching Loaders):
- 一些加载器支持缓存结果,避免重复处理相同的文件。
减少构建时间(Reduce Build Time):
- 例如使用
thread-loader
进行多线程构建,或者使用DllPlugin
预构建一些不会经常变动的模块。
6. TCP三次握手和四次挥手过程
- SYN:同步标志位,置为1时表示请求建立连接,并在三次握手中用于同步序列号。
- ACK:确认标志位,置为1时表示确认号字段有效,用于确认对方的请求或数据。
- Seq:序列号字段,用于标识发送的数据字节流。在三次握手中,Seq的值由发送方随机生成。
- Ack:确认号字段,期望收到对方下一个数据包的序列号。在三次握手中,Ack的值为对方发送的Seq值加1。
7. TCP与UDP区别,TCP 协议怎么保证可靠的,UDP 为什么不可靠,有哪些应用场景?
TCP 与 UDP 的区别:
连接性
- TCP 是面向连接的协议,在通信之前需要进行三次握手建立连接,通信结束后要进行四次挥手释放连接。
- UDP 是无连接的协议,不需要事先建立连接,直接发送数据。
可靠性
- TCP 提供可靠的数据传输服务,通过序列号、确认应答、重传机制、流量控制、拥塞控制等保证数据的正确和有序到达。
- UDP 不保证数据的可靠交付,可能会出现数据丢失、重复、乱序等情况。
有序性
- TCP 会对发送的数据进行排序,确保接收方按顺序接收。
- UDP 不保证数据的有序性。
首部开销
- TCP 首部较长,通常为 20 字节,还可能有选项字段,增加了额外的开销。
- UDP 首部较短,只有 8 个字节。
效率
- TCP 由于有连接建立和维护、可靠传输机制等,效率相对较低。
- UDP 简单直接,效率较高。
TCP 保证可靠的方式:
序列号和确认应答
- 发送方为每个发送的数据段分配一个序列号,接收方对接收到的数据进行确认应答,告知发送方期望收到的下一个序列号,确保数据按序到达。
重传机制
- 如果发送方在一定时间内没有收到确认应答,就会重传数据。
流量控制
- 通过接收方返回的窗口大小信息,控制发送方的发送速度,防止接收方缓冲区溢出。
拥塞控制
- 根据网络的拥塞情况调整发送数据的速度,避免网络拥塞导致数据丢失。
UDP 不可靠的原因:
UDP 只是简单地把应用程序传来的数据加上首部就进行发送,没有建立连接、确认应答、重传、拥塞控制等机制,因此无法保证数据的可靠传输。
应用场景:
TCP 适用于对数据准确性和顺序要求较高的场景,例如:
- 文件传输,如 FTP 协议。
- 电子邮件发送,如 SMTP 协议。
- HTTP 协议,用于网页浏览。
UDP 适用于对实时性要求较高、对数据准确性要求相对较低的场景,例如:
- 视频直播,少量的数据丢失不影响观看体验,但对实时性要求高。
- 在线游戏,快速响应更重要。
- DNS 查询,数据量小,对实时性有要求。
8. 滑动窗口、拥塞控制
滑动窗口:
在 TCP 中,滑动窗口机制用于实现流量控制,以协调发送方和接收方的数据传输速率。
发送方的窗口大小由接收方通告,它表示接收方当前能够接收的数据量。发送方在未收到确认之前,可以连续发送窗口大小范围内的数据。随着确认的收到,窗口向前滑动,发送方可以继续发送新的数据。
例如,假设发送方的窗口大小为 5 个数据包,发送了 1 - 5 号数据包后,在收到 1 - 3 号数据包的确认之前,发送方不能再发送新的数据。当收到 1 号数据包的确认后,窗口向前滑动一个位置,发送方就可以发送第 6 号数据包。
滑动窗口机制有效地提高了数据传输的效率,避免了发送方因为等待每个数据包的确认而造成的空闲时间。
拥塞控制:
TCP 的拥塞控制是为了避免网络拥塞导致的数据丢失和性能下降。拥塞控制的主要策略包括慢启动、拥塞避免、快速重传和快速恢复。
慢启动:
- 初始时,发送方的拥塞窗口大小很小,然后以指数方式增加,直到达到一个阈值。
拥塞避免:
- 当拥塞窗口超过阈值后,窗口大小线性增加,以谨慎的方式试探网络的拥塞情况。
快速重传:
- 当接收方收到失序的数据包时,会立即重复对前一个正确接收的数据包的确认,发送方收到三次相同的确认,就会立即重传丢失的数据包,而不必等待超时。
快速恢复:
- 在快速重传后,拥塞窗口不是降到 1 重新慢启动,而是降到阈值的一半,然后进入拥塞避免阶段。
例如,如果网络状况良好,拥塞窗口会逐渐增大以提高传输效率;但如果出现丢包,就认为可能发生了拥塞,相应地调整拥塞窗口的大小。
拥塞控制使得 TCP 能够在不同的网络环境下自适应地调整传输速度,保证网络的稳定性和公平性。
9. GET和 POST的区别
数据传递方式:
- GET 方法将数据作为 URL 的一部分进行传递,数据附加在 URL 之后,以
?
开头,多个参数之间用&
连接。例如:http://example.com/page?param1=value1¶m2=value2
。- POST 方法将数据放在 HTTP 请求的主体(body)中进行传递。
数据量大小:
- GET 方法对传递的数据量有限制,通常浏览器对 URL 的长度有限制,因此 GET 不适合传递大量数据。
- POST 方法可以传递大量数据,理论上对数据量没有限制,但实际受到服务器处理能力的影响。
安全性:
- GET 方法传递的数据在 URL 中可见,不太安全,不适合传递敏感信息。
- POST 方法传递的数据在请求主体中,相对更安全。
缓存:
- GET 请求可被浏览器缓存。
- POST 请求不会被浏览器缓存。
用途:
- GET 常用于获取数据,例如从服务器获取资源、查询数据等操作。
- POST 常用于提交数据,例如提交表单、上传文件等操作。
10. HTTP状态码有哪些,301和302有什么区别
常见的 HTTP 状态码:
1xx 信息性状态码:
- 100 Continue:表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。
2xx 成功状态码:
- 200 OK:请求成功。
- 201 Created:请求成功并且服务器创建了新的资源。
3xx 重定向状态码:
- 301 Moved Permanently:被请求的资源已永久移动到新位置。
- 302 Found:临时性重定向,表示资源临时被分配了新的 URL。
4xx 客户端错误状态码:
- 400 Bad Request:客户端请求的语法错误,服务器无法理解。
- 401 Unauthorized:请求要求用户的身份认证。
- 403 Forbidden:服务器理解请求客户端的请求,但是拒绝执行此请求。
- 404 Not Found:服务器无法找到请求的资源。
5xx 服务器错误状态码:
- 500 Internal Server Error:服务器内部错误,无法完成请求。
- 502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
301 和 302 的区别:
301 表示永久性重定向,搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址。例如,网站更换了域名,将旧域名永久重定向到新域名,就应该使用 301 状态码。
302 表示临时性重定向,搜索引擎会抓取新的内容而保留旧的网址。比如因为服务器负载均衡的需要,暂时将请求重定向到其他服务器,这种情况适合使用 302 状态码.
举个例子,假设一个电商网站进行了页面结构调整,某个商品页面的 URL 从
www.example.com/productA
变更为www.example.com/new-productA
。如果确定这个变更永久有效,就使用 301 重定向;如果只是短期内因为系统维护等原因进行的临时调整,之后还可能恢复原来的 URL,就使用 302 重定向。
11. 浏览器HTTP请求数目限制,怎么解决
域名分片:将资源分散到不同的域名下,可实现并发数的扩展。
使用 WebSocket 协议:主流浏览器对 WebSocket 连接并发数量的限制都远超6个。
使用 HTTP/2.0:理论上,HTTP/2.0 协议支持在同一个 TCP 连接上发送无限个 HTTP 请求,且这些请求的生命期可以重叠。
需注意的是,虽然 HTTP/2.0 的 RFC 没有要求对 HTTP/2.0 请求强制加密,但是目前主流的浏览器和服务器的实现几乎都要求对 HTTP/2.0 强制加密。
12. 长链接、短链接、如何断开长链接
长链接和短链接:
长链接是指在一个连接上可以连续发送多个请求和响应,在连接保持期间,如果没有数据的读写,需要双方发送链路检测包以维持此连接。长链接可以减少建立和关闭连接的开销,适用于频繁交互的场景,如即时通讯、在线游戏等。
短链接则是指每次请求和响应完成后就关闭连接。它适用于一次性的数据请求,比如网页的加载。
断开长链接的方法:
- 客户端主动关闭:客户端可以通过发送特定的请求或指令来通知服务器关闭连接。
- 服务器端主动关闭:服务器在完成数据交互后,根据预设的规则或条件决定关闭连接。
- 超时机制:如果在一定时间内没有数据传输,连接会因为超时而自动关闭。
13. HTTP 1.0&1.1&2区别
连接复用:
- HTTP 1.0 每次请求都需要建立新的 TCP 连接,请求完成后立即关闭连接。
- HTTP 1.1 支持持久连接(Keep-Alive),即在一个 TCP 连接上可以发送多个请求和响应,减少了连接建立和关闭的开销。
- HTTP 2 采用了多路复用(Multiplexing)技术,多个请求和响应可以在同一个连接上同时传输,无需按顺序等待,极大地提高了传输效率。
请求头:
- HTTP 1.0 的请求头相对简单。
- HTTP 1.1 引入了更多的请求头字段,如
Host
字段用于指定服务器的域名。- HTTP 2 使用二进制格式来编码请求头,减小了头部大小,并且对头部进行了压缩,进一步减少了传输的数据量。
缓存处理:
- HTTP 1.1 增加了更多的缓存控制策略,如
Cache-Control
等。- HTTP 2 对缓存的处理更加优化。
带宽优化:
- HTTP 1.x 不支持请求的优先级设置。
- HTTP 2 允许为每个请求设置优先级,使得高优先级的请求能够更快地得到响应,更有效地利用带宽。
服务器推送:
- HTTP 1.0 和 1.1 中,客户端必须先发起请求,服务器才能响应。
- HTTP 2 支持服务器主动向客户端推送资源,而无需客户端事先请求。
例如:在一个包含大量图片和样式表的网页中,如果使用 HTTP 1.0,每次加载新的资源都要建立新连接,会导致页面加载速度较慢。而 HTTP 1.1 的持久连接能改善这一情况,但仍然可能存在阻塞。HTTP 2 的多路复用和服务器推送则能显著提升页面的加载速度和性能。
14. HTTP2特性
多路复用:
- 允许在单个 TCP 连接上同时发送多个请求和响应,消除了 HTTP/1.x 中的队头阻塞问题,极大地提高了并发处理能力。
二进制分帧:
- 将 HTTP 消息分解为更小的帧,并以二进制格式进行编码,提高了数据传输的效率和解析速度。
头部压缩:
- 使用 HPACK 算法对请求和响应的头部进行压缩,减少了传输的数据量。
服务器推送:
- 服务器可以主动向客户端推送额外的资源,而无需客户端明确请求,提前为客户端准备好可能需要的资源,提高页面加载速度。
请求优先级:
- 客户端可以为每个请求设置优先级,服务器根据优先级来决定处理和响应的顺序,优化资源分配。
例如,对于一个复杂的电商网站页面,HTTP/2 的多路复用特性可以同时加载页面的 HTML、CSS、JavaScript、图片等资源,而不会因为某个资源的阻塞影响其他资源的获取。头部压缩能够显著减少每次请求和响应中头部信息的传输大小,特别是对于频繁发送的小请求,节省了带宽。当用户首次访问该电商网站时,服务器可以通过推送功能提前发送一些常见的图标、样式表等资源,加快后续页面的加载。
15. HTTP2如何加密
HTTP/2 可以通过使用 SSL/TLS 协议来加密客户端和服务器之间的通信。在使用 HTTP/2 时,必须使用 HTTPS 加密协议以确保数据在传输过程中不会被窃听和修改。可以使用 SSL 证书或其他安全协议来实现这一点。
16. HTTP和HTTPS有什么区别
安全性:
- HTTP 是明文传输,数据在网络中以明文形式传递,容易被窃取和篡改。
- HTTPS 在 HTTP 的基础上使用 SSL/TLS 协议进行加密,保证了数据的机密性、完整性和真实性,防止数据在传输过程中被窃取或篡改。
连接方式:
- HTTP 的连接相对简单,直接建立 TCP 连接进行数据传输。
- HTTPS 首先需要进行 SSL/TLS 握手,客户端和服务器协商加密算法、交换密钥等,然后建立安全连接进行数据传输。
端口:
- HTTP 通常使用 80 端口。
- HTTPS 通常使用 443 端口。
证书:
- HTTPS 需要服务器拥有合法的数字证书,以证明其身份的真实性。
- HTTP 不需要证书。
性能:
- 由于 HTTPS 增加了加密和解密的过程,所以在一定程度上会比 HTTP 消耗更多的服务器资源,导致性能略有下降。但随着技术的发展,这种性能差异在逐渐减小。
例如:在一个在线购物网站中,如果使用 HTTP 传输用户的信用卡信息、登录密码等敏感数据,就存在很大的安全风险。而使用 HTTPS 可以确保这些数据在传输过程中是加密的,即使被截获也难以被解读。又比如,一些对安全性要求较高的金融机构网站、政府部门网站等,都会使用 HTTPS 来保障数据的安全传输。
17. HTTPS加密过程、证书是什么
HTTPS 的加密过程主要包括以下步骤:
- 客户端发起 HTTPS 请求:客户端向服务器发送请求,请求连接到服务器的 443 端口。
- 服务器返回数字证书:服务器将自己的数字证书发送给客户端。数字证书包含了服务器的公钥、服务器的名称、证书颁发机构等信息。
- 客户端验证数字证书:客户端使用信任的根证书颁发机构的公钥来验证服务器数字证书的有效性和真实性。如果验证通过,说明服务器是可信的。
- 客户端生成会话密钥:客户端使用服务器的公钥对一个随机生成的会话密钥进行加密,并将加密后的会话密钥发送给服务器。
- 服务器解密获取会话密钥:服务器使用自己的私钥解密客户端发送的加密会话密钥,获取会话密钥。
- 双方使用会话密钥进行加密通信:此后,客户端和服务器使用这个会话密钥对传输的数据进行对称加密和解密,进行安全的通信。
数字证书:
数字证书是一种电子文档,用于证明一个实体(如网站服务器、个人等)的身份,并保证与之通信的对方所获取的公钥是真实有效的。
数字证书通常由权威的证书颁发机构(CA)颁发。证书包含了以下重要信息:
- 所有者的身份信息,如域名、组织名称等。
- 所有者的公钥。
- 数字签名:由证书颁发机构使用其私钥对证书内容进行的签名,用于验证证书的完整性和真实性。
18. Web安全之HTTPS、XSS、CSRF
HTTPS:
HTTPS 通过使用 SSL/TLS 协议对 HTTP 通信进行加密,提供了数据的机密性、完整性和真实性保护。如前面所述,它能有效防止数据在传输过程中被窃取、篡改或伪造,保障用户与网站之间的通信安全,适用于处理敏感信息的场景,如在线支付、登录认证等。
XSS(跨站脚本攻击):
XSS 是一种常见的 Web 攻击方式。攻击者通过在目标网站注入恶意脚本代码,当其他用户访问该网站时,恶意脚本会在用户的浏览器中执行。这可能导致用户的会话信息被盗取、浏览器被劫持、个人隐私泄露等问题。
例如,在一个评论区,如果没有对用户输入的内容进行充分过滤和验证,攻击者可能输入一段恶意的 JavaScript 代码。其他用户查看评论时,浏览器就会执行这段代码,从而造成危害。
CSRF(跨站请求伪造):
CSRF 攻击则是利用用户在已登录网站的信任,诱导用户在不知情的情况下在目标网站执行恶意操作。
比如,用户在某银行网站登录后未退出,攻击者通过诱骗用户访问恶意网站,该网站可以自动向银行网站发送请求(如转账请求),由于浏览器会自动带上用户在银行网站的登录凭证,银行服务器会误以为是合法请求而执行操作。
19. 登录鉴权有哪些方式?登录持久化怎么实现的?
登录鉴权的方式主要有以下几种:
- 基于用户名和密码:这是最常见的方式,用户输入预先设置的用户名和密码,服务器验证其正确性。
- 基于令牌(Token):服务器在用户登录成功后生成一个令牌并返回给客户端,客户端在后续请求中携带该令牌,服务器验证令牌的有效性。
- 单点登录(SSO):用户在一个系统中登录后,可以访问其他相关联的系统而无需再次登录。
- OAuth:允许用户使用第三方账号(如微信、QQ、GitHub 等)登录其他应用。
- 生物识别:如指纹识别、面部识别、虹膜识别等。
登录持久化的实现方式通常有以下几种:
- Cookie:服务器在用户登录成功后,将登录信息(如用户标识、令牌等)存储在 Cookie 中,并设置适当的过期时间。客户端在每次请求时会自动携带 Cookie,服务器通过读取 Cookie 中的信息来确认用户的登录状态。
- Session:服务器在内存中为每个登录用户创建一个会话(Session),并生成一个唯一的 Session ID 发送给客户端。客户端在后续请求中携带 Session ID,服务器通过查找对应的 Session 来确认用户的登录状态。
- 本地存储(LocalStorage/SessionStorage):可以将登录相关的信息存储在浏览器的本地存储中,但需要注意安全性和数据大小限制。
例如:在一个电商网站中,如果使用 Cookie 实现登录持久化,服务器会在用户登录成功后设置一个包含用户标识的 Cookie,并设置其过期时间为一周。在这一周内,用户每次访问该网站,浏览器都会自动发送这个 Cookie,服务器就能识别用户已登录。而对于一些安全性要求较高的金融类应用,可能会更倾向于使用 Session 来实现登录持久化。
20. JWT,accesstoken、refresh token的作用分别是什么,存放在哪儿,具体流程。
JWT(JSON Web Token):
JWT 是一种用于在网络应用中安全地传递声明的开放标准。它通常用于身份验证和授权。
AccessToken(访问令牌):
作用:用于访问受保护的资源,表明用户具有访问特定资源的权限。
存放位置:通常存储在客户端,如浏览器的本地存储(LocalStorage 或 SessionStorage)、Cookie 中。
Refresh Token(刷新令牌):
作用:用于获取新的 AccessToken,当 AccessToken 过期时,使用 Refresh Token 来获取新的有效的 AccessToken,而无需用户重新登录。
存放位置:与 AccessToken 类似,通常存储在客户端的本地存储或 Cookie 中,但由于其重要性,可能会采取更严格的安全措施。
具体流程:
- 用户登录,服务器验证用户名和密码。
- 验证通过后,服务器生成 AccessToken 和 RefreshToken。
- 将 AccessToken 和 RefreshToken 返回给客户端。
- 客户端在后续的请求中携带 AccessToken 访问受保护的资源。
- 服务器验证 AccessToken 的有效性,如果有效则允许访问资源。
- 当 AccessToken 过期时,客户端使用 RefreshToken 向服务器请求新的 AccessToken。
- 服务器验证 RefreshToken 的有效性,如果有效则生成新的 AccessToken 和 RefreshToken 并返回给客户端。
例如:在一个移动应用中,用户登录成功后,应用将获取到的 AccessToken 存储在本地存储中,每次发送请求时携带。当 AccessToken 过期,应用使用存储的 RefreshToken 向服务器申请新的令牌,以保持用户的登录状态,而无需用户再次输入用户名和密码。
21. 性能优化怎么做的(结合资源和代码压缩优化、图片/路由/组件懒加载或者分包、CDN、SSR,HTTP2、浏览器加载和渲染、动画体验等)
资源和代码压缩优化:
- 对于 CSS 和 JavaScript 文件,使用工具如
Webpack
、Gulp
或Grunt
进行压缩,去除空格、注释和缩短变量名,减小文件大小。- 对 HTML 代码进行压缩,去除不必要的空格和换行。
图片优化:
- 选择合适的图片格式,例如对于有大量纯色的图片使用
PNG
,对于照片使用JPEG
。- 压缩图片大小,使用工具如
TinyPNG
或ImageOptim
。- 采用响应式图片,根据不同的屏幕尺寸和分辨率提供合适大小的图片。
路由懒加载:
在单页应用中,当路由切换时,按需加载对应的组件,而不是在初始加载时就加载所有路由组件。例如在Vue
中:const Foo = () => import('./Foo.vue') const routes = [ { path: '/foo', component: Foo } ]
组件懒加载:
与路由懒加载类似,根据实际使用情况加载组件。分包:
将应用按照功能模块或业务逻辑拆分成多个包,避免一次性加载过大的代码包。CDN(内容分发网络):
- 将静态资源(如 CSS、JS、图片等)托管在 CDN 上,利用 CDN 的全球节点加速资源的加载速度。
- 对于常用的库(如
jQuery
、Vue
等),使用 CDN 提供的链接,避免从自己的服务器加载。SSR(服务器端渲染):
- 在服务器端生成初始的 HTML 页面,减少客户端的渲染时间,提高首屏加载速度。
- 对于 SEO 友好的页面,SSR 可以让搜索引擎更好地抓取页面内容。
HTTP/2:
- 启用 HTTP/2 协议,利用其多路复用、头部压缩等特性提高数据传输效率。
浏览器加载和渲染:
- 优化 CSS 和 JavaScript 的加载顺序,将关键的 CSS 放在头部,JavaScript 放在底部(除非需要在页面加载时立即执行)。
- 减少 DOM 操作,避免频繁的重绘和重排。
动画体验:
- 使用硬件加速的动画,如
transform
和opacity
属性,避免使用left
、top
等属性。- 对复杂动画进行性能分析和优化,避免卡顿。
22. CDN原理?CDN优化时如何判断该将哪些包分离
CDN(内容分发网络)的原理:
CDN 是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。
当用户发起请求时,DNS 系统会根据用户的地理位置和网络情况,将用户的请求导向离用户最近且负载较小的缓存服务器。缓存服务器中存有用户请求的内容,如果有,就直接返回给用户;如果没有,缓存服务器会向源服务器请求内容,并将获取到的内容缓存下来,同时返回给用户。
在进行 CDN 优化时,判断哪些包应该分离,可以考虑以下因素:
- 文件大小:较大的文件,如大型的 JavaScript 库、高清图片、视频等,适合分离出来放在 CDN 上。因为这些大文件的下载会占用较多的带宽和时间,通过 CDN 加速可以显著提高加载速度。
- 访问频率:经常被访问的静态资源,例如网站的常用图标、公共样式表等,应该分离到 CDN 以提高访问效率。
- 通用性:具有通用性且在多个页面或应用中都被使用的资源,如一些常用的字体文件、公共组件等,适合放在 CDN 上。
- 变更频率:不经常变更的静态资源更适合放在 CDN 上。因为 CDN 缓存的资源在更新时可能会有一定的延迟,如果资源经常变更,可能会导致用户获取到旧的内容。
23. 在项目中使用postcss-pxtorem
在项目中使用
postcss-pxtorem
可以将 CSS 代码中的像素单位(px)转换为相对单位(rem),从而实现移动端的自适应布局。以下是一般的使用步骤:
安装
postcss-pxtorem
:使用包管理工具(如 npm 或 yarn)安装postcss-pxtorem
插件。配置
postcss-pxtorem
:在项目的根目录下创建一个.postcssrc.js
或postcss.config.js
文件,并在其中配置postcss-pxtorem
插件的选项。常见的配置选项包括:
rootValue
:指定转换的基准值,通常根据设计稿的宽度设置。propList
:指定需要转换的属性列表,一般设置为'*'
表示所有属性。selectorBlackList
:指定不需要转换的选择器列表。在 CSS 代码中使用像素单位:在需要转换的 CSS 代码中,使用像素单位(px)来定义尺寸、边距、字体大小等。
构建或编译项目:在项目的构建或编译过程中,
postcss-pxtorem
插件会自动将像素单位转换为 rem 单位。通过使用
postcss-pxtorem
,可以根据不同的屏幕尺寸自动调整页面元素的大小,实现移动端的自适应布局。这样可以提高页面在不同设备上的显示效果和用户体验。