前端进阶--BOM浏览器对象
1、实用的BOM属性对象方法1.1、location对象location.href– 返回或设置当前文档的URLlocation.search – 返回URL中的查询字符串部分。例如 http://www.dreamdu.com/dreamdu.php?id5namedreamdu 返回包括(?)后面的内容?id5namedreamdulocation.hash – 返回URL#后面的内容如果没有#返回空location.hostname – 返回URL中的主域名部分例如例如www.dreamdu.comlocation.pathname – 返回URL的域名后的部分。例如 http://www.dreamdu.com/xhtml/ 返回/xhtml/location.port – 返回URL中的端口部分。例如 http://www.dreamdu.com:8080/xhtml/ 返回8080location.protocol – 返回URL中的协议部分。例如 http://www.dreamdu.com:8080/xhtml/ 返回(//)前面的内容http:location.assign() – 重定向页面与location.href一样会记录历史能后退页location.replace() – 设置当前文档的URL不记录历史不能后退页面location.reload() – 重载当前页面,相当于F5。添加参数true则表示强制刷新直接从服务器获取数据不从浏览器缓存中取数据相当于CtrlF51.2、history对象history.go(n) – 前进或后退指定的页面数;history.back() – 后退一页history.forward() – 前进一页history.pushState(object, title, url)方法接受三个参数object 为随着状态保存的一个对象title为新页面的标题url为新的网址。replaceState(object, title, url) 与pushState的唯一区别在于该方法是替换掉history栈顶元素。onpopstateHistory.back()、History.forward()、History.go()事件是会触发popstate事件的但是History.pushState()和History.replaceState()不会触发popstate事件。onhashchange事件当#值发生变化时就会触发这个事件虽然使用History.pushState与History.replaceState可以改变URL并且页面不会刷新但这并不会阻止浏览器去获取新的资源。location.href与history.pushState的区别1.使用location.href跳转后页面会发起新的文档请求而history.pushState不会。 2.location.href可以跳转到其他域名而history不能。3.location.href与history都会往历史列表中添加一条记录。1.3、navigator对象navigator对象用于提供当前浏览器及操作系统等信息navigator.userAgent – 返回用户代理头的字符串表示(就是包括浏览器版本信息等的字符串)navigator.cookieEnabled – 返回浏览器是否支持(启用)cookie2、浏览器与浏览器的内核IE:ie浏览器-- trident内核Firefox火狐浏览器--gecko内核Safari:苹果浏览器--webkit内核Opera:欧朋浏览器--以前是presto内核现已改用Blink内核。Chrome:谷歌浏览器--Blink3、知道的网页制作会用到的图片格式有哪些gifjpgpngWebPsvg格式WebP谷歌google开发的gif适用于动图jpg色彩丰富有损压缩适用于色彩丰富的图像如风景和人物照片png无损压缩色彩少一些适用于有透明要求不需要特别丰富色彩的图像WebP适用于网页但是目前兼容性稍差项目打包时webpack如何压缩图片上传后续补充4、浏览器内存4.1、栈内存和堆内存原理浏览器打开页面会分配一块提供代码执行环境的内存基本数据类型存在栈内存中引用数据类型存在堆内存中。引用数据类型值是先开辟一个堆内存把东西存储进去最后把地址放到栈中供变量关联使用。4.2、栈内存和堆内存的垃圾回收:栈内存中变量一般在它的当前执行环境结束就会被销毁被垃圾回收制回收 而堆内存中的变量则不会因为不确定其他的地方是不是还有一些对它的引用。 堆内存中的变量只有在所有对它的引用都结束的时候才会被回收。4.3、浏览器通常使用的垃圾回收方法有两种标记清除引用计数。标记清除是浏览器常见的垃圾回收方式当变量进入执行环境时就标记这个变量“进入环境”被标记为“进入环境”的变量是不能被回收的因为他们正在被使用。当变量离开环境时就会被标记为“离开环境”被标记为“离开环境”的变量会被内存释放。引用计数就是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量时则这个值的引用次数就是1。相反如果包含对这个值引用的变量又取得了另外一个值则这个值的引用次数就减1。当这个引用次数变为0时说明这个变量已经没有价值因此在在机回收期下次再运行时这个变量所占有的内存空间就会被释放出来。4.4、哪些情况会导致内存泄漏以下四种情况会造成内存的泄漏参考前端常见内存泄漏及解决方案 - 掘金 (juejin.cn)意外的全局变量 由于使用未声明的变量而意外的创建了一个全局变量而使这个变量一直留在内存中无法被回收。变量在窗口关闭或重新刷新页面之前都不会被释放。被遗忘的计时器或回调函数 设置了 setInterval 定时器而忘记取消它如果循环函数有对外部变量的引用的话那么这个变量会被一直留在内存中而无法被回收。脱离 DOM 的引用 获取一个 DOM 元素的引用而后面这个元素被删除由于一直保留了对这个元素的引用所以它也无法被回收。闭包 不合理的使用闭包从而导致某些变量一直被留在内存当中。参考对闭包的理解JS闭包与内存泄漏 - 掘金 (juejin.cn)5、浏览器URL统一资源定位器在www上每一个资源都有都有统一的且在网上唯一的即url,如下所示http://www.aspxfans.com:8080/news/index.asp?boardID5ID24618page1#nameURL由三部分组成资源类型、存放资源的主机域名、资源文件名。也可认为由5部分组成协议http、主机www.aspxfans.com、端口8080、路径news/index.asp、qurry参数:boardID5ID24618page15.1、协议file 资源是本地计算机上的文件。格式file:///注意后边应是三个斜杠。ftp 通过 FTP访问资源。格式 FTP://http 通过 HTTP 访问该资源。 格式 HTTP://https 通过安全的 HTTPS 访问该资源。 格式 HTTPS://5.2、hostname主机名是指存放资源的服务器的域名系统(DNS) 主机名或 IP 地址。有时在主机名前也可以包含连接到服务器所需的用户名和密码格式username:passwordhostname。域名:以www.bilibili.com举例www代表主机名主机名与域名组成子域名子域名可对网站进行业务分类。bilibili.com代表域名它便于记忆配合域名与IP地址的绑定和解析方便大家上网在网络进程接收到 URL 后需要进行 DNS 解析域名得到对应的 IP然后通过 ARP 解析 IP 得到对应的 MAC地址。5.3、port端口号HTTP 默认端口号80HTTPS 默认端口号443FTP 默认端口号215.4、请求路径文件名部分“/”之后-?之前 的部分5.5、query(查询)/传参传递参数可有多个参数用“”符号隔开每个参数的名和值用“”符号隔开。问号传参?xxxxxx…直到“#”之前5.6、锚部分哈希值从“#”开始到最后都是锚部分。锚部分也不是一个URL必须的部分6、补充路由与url的请求路径的关系6.1、params与querry传参可以使用params和query两种方式。使用params传参只能用name来引入路由。即push里面只能是name:’xxxx’,不能是path:’/xxx’,因为params只能用name来引入路由如果这里写成了path接收参数页面会是undefined。使用query传参使用path来引入路由。params是路由的一部分,必须要在路由后面添加参数名。query是拼接在url后面的参数没有也没关系。注意params是路由的一部分,必须要在路由后面添加参数名。query是拼接在url后面的参数没有也没关系。params一旦设置在路由params就是路由的一部分如果这个路由有params传参但是在跳转的时候没有传这个参数会导致跳转失败或者页面会没有内容。params//params传参 使用name this.$router.push({ name:second, params: { id:2023, name: query } }) //params接收参数 this.id this.$route.params.id ; this.name this.$route.params.name ; //路由配置 { path: /second/:id/:name, name: second, component: () import(/view/second) } //url为localhost:8080/#/second/2023/paramsquerry//query传参使用name跳转 this.$router.push({ name:second, query: { queryId:2020, queryName: query } }) //query传参使用path跳转 this.$router.push({ path:second, query: { queryId:2023, queryName: query } }) //query传参接收 this.queryName this.$route.query.queryName; this.queryId this.$route.query.queryId; //路由 { path: /second, name: second, component: () import(/view/second) } //url为localhost:8080/#/second?queryId2023queryNamequery可以理解为nameparamspath,即一个URL路径。6.2、服务端路由对于服务器来说当接收到客户端发来的HTTP请求会根据请求的URL来找到相应的映射函数然后执行该函数并将函数的返回值发送给客户端。对于最简单的静态资源服务器可以认为所有URL的映射函数就是一个文件读取操作。对于动态资源映射函数可能是一个数据库读取操作也可能是进行一些数据的处理等等。app.get(/, (req, res) { res.sendFile(index) }) app.get(/users, (req, res) { db.queryAllUsers() .then(data res.send(data)) })参考理解Web路由 - 知乎 (zhihu.com)6.3、前端路由原理前端路由的原理本质上就是在不刷新浏览器的请求下修改URLwindow.history.replaceState、检测URL的变化截获URL的地址通过解析、匹配路由规则从而实现UI的更新。路由的实现通常有两种形式一种是Hash模式一种是History模式。运用于单页面应用单页面应用指的是第一次进入页面的时候会请求一个html文件切换到其他组件的时候虽然路径会发生相应的变化但是没有新的html文件请求原理是JS会感知到url的变化然后js会动态的将当前页面的内容清除掉然后将下一个页面的内容挂载到当前的页面上这个时候的路由不是由后端做的而是由前端来做的来判断页面到底显示哪个组件这个过程就是单页面的应用。// 改变URL window.history.pushState({}, , /new-url); // 监听URL改变事件 window.addEventListener(popstate, function(event) { console.log(URL changed: document.location.href); });补充多页面应用依靠URL、Cookie、LocalStorage来传递数据单页面应用则是靠组件进行通信相对更加简单。7、跨域url的不同7.1、 为什么会有同源策略同源策略指的是浏览器只允许页面从同一个源加载其他资源不同源的客户端脚本在没有明确授权的情况下不能读写对方的资源。CSRF跨站请求伪造攻击攻击者通过伪造一个合法的请求正确的请求方式诱使已登录身份的用户存在Cookie 用户点击从而盗取用户在其他网站的信息或者进行非法操作。同源策略可以阻止第三方网站向目标网站发送跨域请求从而防止攻击者在目标网站上执行恶意操作。例如攻击者可以伪造一个图片链接让用户点击该链接从而触发向目标网站发送的恶意请求执行攻击者预设的操作例如转账、修改密码等。在HTTP协议中每一个异步请求都会携带两个Header用于标记来源域名判断是否同源非跨域请求在请求头中会只包含请求的主机名。host记录该请求的客户端来源地址。跨域请求在请求头中会既包含要请求的主机名host还包括当前的源主机名Origin如果这两者不一致那就是跨域请求了。host与Referer一样Origin记录该请求的服务器域名信息CSRF的另一个特征是攻击者无法直接窃取到用户的信息CookieHeader网站内容等仅仅是冒用Cookie中的信息。通常 CSRF 攻击都是从第三方站点发起的冒用受害者在被攻击网站的登录凭证所以我们可以做以下防护如果是从第三方站点发起的请求浏览器禁止发送某些关键 Cookie 数据到服务器如果是同一个站点发起的请求那么就需要保证 Cookie 数据正常发送。将 SameSite 设置为Strict或Lax来解决 Cookie 问题利用同源策略Token 认证7.2、跨域问题的产生浏览器的同源策略限制会对非同源的请求进行拦截会导致不同源的请求会造成跨域报错。只有协议, 域名和端口号完全匹配文件地址与请求参数不一样没关系才是同源。协议、域名与端口号中 只要有一个不相同就是非同源策略。浏览器的同源策略把跨域请求都禁止了但是页面中的scriptimglink的连接跳转不设防。笔试题7.3、如何解决跨域同源策略安全性主要表现在 DOM、web 数据 和 网络 这三个层面DOM层面同源策略限制了来⾃不同源的 JavaScript 脚本对当前 DOM 对象读和写的操作。危害。恶意链接通过iframe内嵌网页进来的。那么此时如果你在里面输入账号密码主网站就可以通过跨域访问到银行网站的dom节点以至于拿到用户输入的关键机密信息。数据层面同源策略限制了不同源的站点读取当前站点的Cookie数据网络层面 同源策略限制了通过 XMLHttpRequestAjax请求 等方式将站点的数据发送给不同源的站点为什么要解决跨域我们的开发或在实际生成环境中肯定会有很多台服务器之间交互地址和端口都可能不同无法进行交互此时需要解决跨域。跨域解决方案开发环境本地调试方案 1前端代理Vite / Webpack proxy最常用export default defineConfig({ server:{ proxy:{ /api:{ target:http://后端真实地址, changeOrigin:true, // 修改请求头origin为目标域名 rewrite:(path)path.replace(/^\/api/,) } } } })原理浏览器请求本地 dev 服务器dev 服务器帮我们转发请求到后端浏览器只和本地服务通信没有跨域。 ⚠️重要proxy 只在开发环境生效打包上线后失效生产环境不能靠 proxy。方案 2CORS后端配置生产环境线上1. 后端开启 CORS首选后端配置跨域响应头允许线上前端域名。注意不要写*通配符生产环境不安全指定具体域名。7.3.1、JSONP代理(不用)参考同源策略是怎么预防攻击的跨域的代码实现、原理和漏洞 - 掘金 (juejin.cn)原理因为所有的src属性和href属性都不受同源策略限制。可以请求第三方服务器数据内容。JSONP 的理念就是与服务端约定好一个回调函数名服务端接收到请求后将返回一段 Javascript代码在这段 Javascript 代码中调用了约定好的回调函数并且将数据作为参数进行传递。步骤1. 去创建一个script标签2. script的src属性设置接口地址3. 接口参数,必须要带一个自定义函数名 要不然后台无法返回数据。4. 通过定义函数名去接收后台返回数据//前端 function jsonp(url, callback) { const script document.createElement(script); script.src url ?callback callback; document.body.appendChild(script); } function handleData(data) { console.log(data); } jsonp(http://example.com/data, handleData); //nodejs app.get(/data, (req, res) { const data { name: hyhyhy }; const callback req.query.callback; const jsonp callback ( JSON.stringify(data) ); res.send(jsonp); });7.3.2、跨域资源共享CORS跨域资源共享CORS是一个机制允许 Web 应用程序从不同的域访问其资源。服务器可以通过在响应头中添加 Access-Control-Allow-Origin 属性来允许该来源的访问const Koa require(koa); const app new Koa(); app.use(async (ctx, next) { ctx.set(Access-Control-Allow-Origin, *); ctx.set(Access-Control-Allow-Methods, GET, POST, OPTIONS); ctx.set(Access-Control-Allow-Headers, Content-Type, Authorization); // 令牌 ctx.set(Access-Control-Allow-Credentials, true); // 处理预检请求 if (ctx.method OPTIONS) { return ctx.status 204; } await next(); }) app.listen(3000, () { console.log(Server started on http://localhost:3000); });7.3.3、反向代理一种利用服务器http模块代理转发请求的方法7.3.4、websocket不理解有待学习8.xss跨站脚本攻击8.1、什么是xss攻击跨站脚本攻击Cross-Site Scripting是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本诱导用户在浏览器上运行该脚本。利用这些恶意脚本攻击者可获取用户的敏感信息如 Cookie、SessionID 等进而危害数据安全。8.2、XSS 常见的注入方法在 HTML 中内嵌的文本中恶意内容以 script 标签形成注入8.2.1、反射型 XSS常见的是恶意链接。反射型XSS 的攻击步骤攻击者构造出特殊的 URL其中包含恶意代码。用户打开带有恶意代码的 URL 时网站服务端将恶意代码从 URL 中取出拼接在 HTML 中返回给浏览器服务器端为什么会将恶意代码从url中取出并返回给浏览器。用户浏览器接收到响应后解析执行混在其中的恶意代码也被执行。恶意代码窃取用户数据并发送到攻击者的网站或者冒充用户的行为调用目标网站接口执行攻击者指定的操作。8.2.2、DOM型 XSS基于DOM文档对象模型的 XSS。如果用户在客户端输入的数据包含了恶意的js脚本的话但是这些脚本又没有做任何过滤处理的话那么我们的应用程序就有可能受到DOM-based XSS的攻击。步骤如下攻击者构造出特殊的 URL其中包含恶意代码。用户打开带有恶意代码的 URL。用户浏览器接收到响应后解析执行前端 JavaScript 取出 URL 中的恶意代码并执行。恶意代码窃取用户数据并发送到攻击者的网站或者冒充用户的行为调用目标网站接口执行攻击者指定的操作。当利用步骤和反射型很类似但是唯一的区别就是构造的URL参数不用发送到服务器端DOM 型 XSS 攻击实际上就是网站前端 JavaScript 代码本身不够严谨把不可信的数据当作代码执行了。在使用 .innerHTML、.outerHTML、document.write() 时要特别小心不要把不可信的数据作为 HTML 插到页面上而应尽量使用 .textContent、.setAttribute() 等。8.3.3、存储型 XSS存储型XSS的原理是主要是将恶意代码上传或存储到服务器中下次只要受害者浏览包含此恶意代码的页面就会执行恶意代码。响应数据解释时8.2.4、区别反射型XSS 跟存储型 XSS 的区别是存储型 XSS 的恶意代码存在数据库里反射型 XSS 的恶意代码存在 URL 里。DOM 型 XSS 攻击中取出和执行恶意代码由浏览器端完成属于前端 JavaScript 自身的安全漏洞而其他两种 XSS 都属于服务端的安全漏洞。8.3、常用防范方法httpOnly: 在 cookie 中设置 HttpOnly 属性后js脚本将无法读取到 cookie 信息。输入过滤: 一般是用于对于输入格式的检查转义 HTML: 如果拼接 HTML 是必要的就需要对于引号尖括号斜杠进行转义,但这还不是很完善.想对 HTML 模板各处插入点进行充分的转义,就需要采用合适的转义库.9、浏览器存储前端浏览器存储方式一共是5种cookies、local storage、session storage、indexedDB、web sql本文将分别就大小有效期和使用方法等方面进行阐述。9.1、cookies9.1.1、cookie传输过程Cookie 是通过浏览器将服务器返回的数据保存在本地的一小块数据一般小于4kb。首先浏览器发送请求服务器收到 HTTP 请求时服务器可以在响应头里设置一个Set-cookie选项浏览器接收到响应后会自动保存下 Cookie之后浏览器会自动在请求头携带上 Cookie 数据。如果不设置时间就以浏览器生命周期为准设定时间后存储在本地硬盘。以设置时间为准过期自动删除。9.1.2、Cookie 的意义引入 Cookie 的意义是因为 HTTP 的请求是无状态的其有一下功能会话状态管理如用户登录状态、及其他需要记录的信息个性化设置如用户自定义设置浏览器追踪行为如追踪分析用户行为9.1.3、cookie的字段name、value、domain、path、expires/max-age、size、httpOnly、secure、sameSiteExpires/Max-age指的是cookie的有效期expires是cookie失效的时间戳服务器时间 max-age是几秒后失效单位为秒。不设置的话默认值是Session意思是cookie会和Session一起失效。当浏览器关闭不是浏览器标签页是整个浏览器后此cookie失效。其过期后当用户再次访问某个站点时服务端将要求浏览器查找并返回先前发送的Cookie信息来识别这个用户。如果同时使用max-age会生效。标记为 secure 的 Cookie 只应通过被 Https 协议加密过的请求发送给服务端。通过 https 创建的 Cookie 只能通过 Https 请求将 Cookie 携带到服务器通过 http 无法拿到 CookiesomeSize:Strict: 浏览器只会在相同站点下发送 Cookies{httpOnly:true则只有在http请求头中会带有此cookie的信息而不能通过document.cookie来访问此cookie。Cookies.set(token,dsafdsfd453542scdsfd,{httpOnly:true})9.1.4、共享cookie不同浏览器不共享最常用的例子就是让 cookie 在根目录下,这样不管是哪个子页面创建的 cookie所有的页面都可以访问到了document.cookie ‘key value;path/;domaincsdn.cn’9.2、local storage与session storage一般为5M左右只能存储字符串格式的数据所以存储前需要JSON.stringify()转换成json串需要时取出再转换。local storage默认是永久生效。session storage是会话存储标签页关闭就会清除。相同浏览器下并且是同源窗口协议、域名、端口一致不同页面可以共享localStorageCookies值通过跳转的页面可以复制上一个页面的sessionStorage值。不同源情况都不能共享。换句话说打开多个相同的 URL 的 Tabs 页面会创建各自的sessionStorage。但是不会改变localStorageCookies值。总结localStorage是同一个浏览器同源下永久共享数据。sessionStorage是在保存当前页面的临时数据当切换页面不同项目或关闭页面时无效。刷新页面还会保留vuex刷新不保留跳转的方式//保存数据 localStorage.setItem(key,value); sessionStorage.setItem(Author, session); //读取数据 localStorage.getItem(key); sessionStorage.getItem(Author); //删除单个数据 localStorage.removeItem(key); sessionStorage.removeItem(Author); //删除所有数据 localStorage.clear(); sessionStorage.clear(); //得到某个索引的key localStorage.key(index);9.3、indexedDB参考前端数据存储之indexDB - 掘金 (juejin.cn)前端本地存储数据库IndexedDB完整教程 - 掘金 (juejin.cn)IndexDB 是一个运行在浏览器上的非关系型数据库。异步存储不堵塞。无限制存储上不封顶。永久保存除非设置了清除。9.4、web sqlWebSQL 是浏览器端的关系行数据库引入了一组使用 SQL 操作客户端数据库的 API。刷新当前页面or 关闭当前页面失效无大小限制。三个核心方法openDatabase使用数据库或新建数据库来创建数据库对象transaction允许我们根据情况控制事务提交或回滚executeSql这个方法用于执行真实的 SQL 查询10、token的认证参考基于Token 认证和session 认证的比较 - 想飞_毛毛虫 - 博客园 (cnblogs.com)HTTP 是无状态的。也就是说HTTP 请求方和响应方间无法维护状态基于cookie是*有状态的statefull。基于token是无状态stateless10.1、基于账号密码的cookie登录首次客户端登陆一般输入用户名和密码服务端如果验证通过就会生成cookie并把它存入数据库中响应头中返回set-cookie客户端在浏览器上会产生cookie(name:用户名value:密码不安全客户端后续有新的请求会在请求头中自动携带cookie,发给服务端服务端判断是否存在cookie存在就正常响应。如果客户端登陆出去下次从浏览器本地存储里获取cookie进行登录。假如是非首次登录是如何记住之前的登录状态浏览器本地存储了cookie,会根据域名与路径匹配出cookie,随浏览器发送给服务器服务器就知道了客户端是登录状态。存在CRSF攻击前端可以通过document.cookie来访问cookie。伪造请求如何防止方案一放弃Cookie、使用Token方案二SameSite Cookies。方案三服务端Referer验证。10.2、基于sesision的cookie登录客户端登陆一般输入用户名和密码服务端如果验证通过就会生成session里面value有唯一的sessionID,安全)并把它存入数据库中响应头中返回set-cookie的形式把含有session的cookie写入客户端客户端后续有新的请求都会在请求后携带sessIon发给服务端。服务器就从存储在服务器上的无数session信息中去查找客户端请求时带过来的cookie的状态。如果服务器中没有这条session信息则添加一条session信息。响应数据。如果客户端登陆出去log out该生成的session就会在客户端和服务端都被销毁。主要看cookie的设置时间吧。区别1.cookie数据保存在客户端session数据保存在服务端服务器负担重。如果浏览器使用的是cookie那么所有数据都保存在浏览器端比如你登陆以后服务器设置了cookie用户名那么当你再次请求服务器的时候浏览器会将用户名一块发送给服务器这些变量有一定的特殊标记。客户端每次请求服务器的时候会发送当前会话sessionid服务器根据当前sessionid判断相应的用户数据标志以确定用户是否登陆或具有某种权限。由于数据是存储在服务器上面所以你不能伪造。2.session过期与否取决于服务器的设定。cookie过期与否可以在cookie生成的时候设置进去。10.3、使用token认证客户端用自己的机密信息登陆如用户名和密码服务端验证验证通过生成Token利用JWT生成的字符串返还给客户端。客户端把Token写入local storage(本地内存)后续请求都携带该Token服务端收到请求时验证Token就进行解析验证如果验证通过则允许用户访问相应资源token是什么客户端登陆成功后服务端会生成一个token并把它返还给客户端由于是无状态的服务端不再保存该Token。JWTJson web token一种基于JSON的开放标准为了网络应用环境间传递被认证的声明。JWT生成 的token由三部分构成头部header),载荷payload)签证signature)头部承载两部分信息声明类型与声明加密的算法 { type: JWT, alg: HS256}。然后利用base64加密。载荷分为公有与私有部分私有部分存放有效信息的地方如用户名与密码{ sub: 1234567890, name: John Doe, admin: true}。然后利用base64加密。签证信息由三部分组成需要base64加密后的header和base64加密后的payload使用.连接组成的字符串(头部在前)然后通过header中声明的加密方式进行加盐secret组合加密然后就构成了jwt的第三部分。密钥secret是保存在服务端的是所有用户公用的统一值。服务端会根据这个密钥进行生成token和验证所以需要保护好。对于采用密钥对称加密生成的 Token一般其中包含用户ID和生成时间戳等信息由于只有服务器拥有密钥其他任何第三方包括客户端无法伪造 Token所以只要服务器可以通过密钥正常解析 Token 且未过期并且通过用户ID可以从数据库获取到用户信息则可以认为本次 Token 认证成功。那么token保存在浏览器缓存里前端如何每次请求都携带上呢首先会在请求拦截器中对进行判断是否已经登录如果登录了就会在请求头的Authorization里携带token。如果响应页面报错就判断是未登录还是token出现问题跳往登录页。对于通过路径导航到其他页面需要判断是否登录了才跳转。// http request 请求拦截器有token值则配置上token值 axios.interceptors.request.use( config { if (token) { // 每次发送请求之前判断是否存在token如果存在则统一在http请求的header都加上token不用每次请求都手动添加了 config.headers.Authorization token; } // sratload(); return config; }, err { return Promise.reject(err); }); // http response 服务器响应拦截器这里拦截401错误并重新跳入登页重新获取token axios.interceptors.response.use( response { // if (response.status 200 || response.status 201){ // endload(); // } return response; }, error { if (error.response) { console.log(error.response.status) if(error.response.status 401){ alter.error(登陆失效,请重新登录!); localStorage.removeItem(token); setTimeout(function () { location.href /index.html; }, 2000); } } // return Promise.reject(error.response.data) });11、从输入URL地址到看到页面中间都经历了什么从浏览器输入 URL 到页面渲染的整个过程都是由 Chrome 架构中的各个进程之间的配合完成。参考之前文章的“进程”理解参考推荐「2021」高频前端面试题汇总之计算机网络篇 - 掘金 (juejin.cn)概括用户在地址栏中输入了 URL而地址栏会根据用户输入做出如下判断输入的是非 URL 结构的字符串则会用浏览器默认的搜索引擎搜索该字符串。输入的是 URL 结构字符串则会构建完整的 URL 结构浏览器进程会将完整的 URL 通过进程间通信发送给网络进程。在网络进程接收到 URL 后需要进行DNS 解析域名得到对应的 IP然后通过ARP 解析 IP得到对应的 MAC地址。然后通过http五层模型进行通信。最后进行浏览器渲染页面。11.1、在浏览器地址栏输⼊URL11.2、DNS域名解析浏览器解析URL获取协议主机端⼝path。然后浏览器组装⼀个HTTPGET请求报⽂接着进行DNS域名解析DNS 是域名系统提供的是一种主机名到 IP 地址的转换服务。11.2.1、DNS服务器解析域名的过程第一步本地客户机提出域名解析请求查找浏览器的缓存与本地HOST文件如果查找到直接返回若找不到后将该请求发送给本地域名服务器。第二步当本地的域名服务器收到请求后就先查询本地的缓存如果有该纪录项则本地的域名服务器就直接把查询的结果返回。若找不到继续下一步如果本地DNS缓存中没有该纪录则本地域名服务器就直接把请求发给根域名服务器然后根域名服务器再返回给本地域名服务器一个所查询域根的子域的主域名服务器的地址例如music.biadu.com,请求域名为.com域则返回负责.com域解析的主域名服务器——辅助服务器。本地DNS服务器向顶级域名服务器发送请求接受请求的服务器查询自己的缓存如果有记录就返回查询结果如果没有就返回相关的下一级的权威域名服务器的地址本地DNS服务器向权威域名服务器发送请求域名服务器返回对应的结果本地DNS服务器将返回结果保存在缓存中便于下次使用本地DNS服务器将返回结果返回给浏览器11.2.2、递归查询与迭代查询递归查询指的是查询请求发出后域名服务器代为向下一级域名服务器发出请求最后向用户返回查询的最终结果。使用递归 查询用户只需要发出一次查询请求。迭代查询指的是查询发出请求后域名服务器返回单次查询的结果。下一级的查询由用户自己请求。使用迭代查询用户需要发出多次的查询请求。一般我们向本地 DNS 服务器发送请求的方式就是递归查询因为我们只需要发出一次请求然后本地 DNS 服务器返回给我 们最终的请求结果。而本地 DNS 服务器向其他域名服务器请求的过程是迭代查询的过程因为每一次域名服务器只返回单次 查询的结果下一级的查询由本地 DNS 服务器自己进行。11.3、浏览器查看缓存先检测是否有强缓存有且未失效走强缓存。没有或已失效走协商缓存检测是否有协商缓存有就会发一个请求到服务器验证协商缓存是否命中过期11.3.1、如果请求资源在缓存中并且新鲜走强缓存。检验新鲜通常有两个HTTP头进⾏控制 Expires 和 Cache-ControlHTTP1.0提供 Expires是一个时间戳缺点是采用的是本机的绝对时间可以修改HTTP1.1增加了Cache-Control相对时间: max-agetime缓存内容将在xxx秒后失效缓存检查过程和expires一致同时存在时优先级高于expiresCache-ControlCache-Control: max-age300private/public/immutable表示服务器再次获取该资源时没有超过300s 则命中缓存Cache-Control: no-cache表示当前资源跳过强缓存可以使用协商缓存如果有Cache-Control: no-store不使用任何缓存包括强缓存和协商缓存强制服务器返回资源private代理服务器不能缓存资源只有客户端本地可以缓存,public大家都可以缓存这个资源,Cache-Control:immutable表示该资源永远不变刷新页面的时候不要去请求服务器请求过程第一次请求资源时浏览器正常请求服务器正常返回资源并在响应头中回传资源的缓存策略。前端缓存主要是通过设置HTTP响应头来实现的。在浏览器发送HTTP请求时可以在HTTP响应头中添加Expires、Cache-Control等字段告诉浏览器该资源的缓存时间和过期时间。第二次请求资源时浏览器判断这些请求参数击中强缓存则拦截请求并读取浏览器缓存而且没有过期将缓存返回浏览器并返回一个200响应。否则就把请求参数加到请求头中传给服务器查看是否击中协商缓存击中则返回304否则服务器会返回新的资源。这是缓存运作的一个整体流程图浏览器会根据请求头部携带的Cache-Control或者Expires来尝试命中强缓存强缓存的原理是为资源文件设置一个时间只要没超过这个时间都使用缓存不管服务器文件是否更新。11.3.2、协商缓存是利用的是两对Header参考彻底弄懂强缓存与协商缓存 - 简书 (jianshu.com)第一对Last-Modified、If-Modified-Since该资源在服务器上的最后修改时间第二对ETag、If-None-Match资源的唯一标识HTTP1.1增加了浏览器如果收到304的响应就会从缓存中加载资源。last-modified文件的修改时间精确到秒。在访问资源的时候客户端发起的请求是由浏览器代理的所以我们不需要设置客户端请求的头部都交给浏览器来就行了。如果要开启协商缓存服务器只需要在响应头加上Last-Modified即可浏览器收到之后会自动配置请求头if-modified-since要注意客户端第一次请求的时候请求头是不会if-modified-since的只有第二次之后会有。浏览器第一次请求一个资源的时候服务器返回的header中会加上Last-ModifyLast-modify是一个时间标识该资源的最后修改时间例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。当浏览器再次请求该资源时request的请求头中会包含If-Modify-Since该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后根据资源的最后修改时间判断是否命中缓存。如果命中缓存则返回304并且不会返回资源内容并且不会返回Last-Modify。etag每个文件有一个改动文件了就变了就是个文件hash每个文件唯一。每次请求返回来 response header 中的 etag和 last-modified在下次请求时在 request header 就把这两个带上服务端把你带过来的标识进行对比然后判断资源是否更改了如果更改就直接返回新的资源和更新对应的response header的标识etag、last-modified。如果资源没有变那就不变etag、last-modified这时候对客户端来说每次请求都是要进行协商缓存了客户端会通过If-None-Match头将先前服务器端返回的Etag发送给服务器服务器会对比这个客户端发过来的Etag是否与服务器的相同若相同就将If-None-Match的值设为false返回状态304客户端继续使用本地缓存不解析服务器端发回来的数据。若不相同就将If-None-Match的值设为true返回状态为200客户端重新机械服务器端返回的数据对比Last-Modified与ETag是可以一起使用的服务器会优先验证ETag一致的情况下才会继续比对Last-Modified最后才决定是否返回304。CtrlF5 的“强制刷新”其实是发了一个“Cache-Control: no-cache”有了last-modified为什么新增Etag???为了解决几个last-modified比较难解决的问题一些文件也许会周期性的更改但是他的内容并不改变(仅仅改变的修改时间)这个时候我们并不希望客户端认为这个文件被修改了而重新get某些文件修改非常频繁比如在秒以下的时间内进行修改(比方说1s内修改了N次)if-modified-since能检查到的粒度是秒级的这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)某些服务器不能精确的得到文件的最后修改时间。11.4、端⼝建⽴TCP链接数据传输。三次握⼿如下客户端发送⼀个TCP的SYN1请求建立链接SeqX随机号的包到服务器端口服务器发回SYN1 ACK1回应请求 SeqYackX1的响应包客户端发送ACK1 SeqX1,ackY111.5、TCP链接建⽴后发送HTTP请求客户端发送请求申请断开连接进入等待阶段此时不会发送数据但是会继续接收数据。FIN1其序列号为sequ服务端接收请求后告知客户端已明白此时服务端进入等待状态不会再接收数据但是会继续发送数据。ACK1acku1并且带上自己的序列号seqv客户端收到后进入下一阶段等待。服务端发送完剩余的数据后告知客户端可以断开连接此时服务端不会发送和接收数据。FIN1ACK1acku1seqw客户端收到后告知服务端我开始断开连接。FIN1ACK1ackw1sequ1服务端收到后开始断开连接。11.5.1、TCP实现原理和为什么需要三次握手两次握手不可以四次握手不可以如果只设计成两次握手的情况服务端只能一直接收请求然后返回请求信息也不知道客户端是否请求成功。这些过期请求的话就会造成网络连接的混乱。然后可以设计成四次握手也是可以的不过为了节省资源三次握手就可以符合实际情况所以就没必要设计成四次握手等等情况11.5.2、为什么要四次挥手三次不行吗关闭连接时当服务端收到 FIN 报文时很可能并不会立即关闭 SOCKET所以只能先回复一个 ACK 报文告诉客户端“你发的 FIN 报文我收到了”。只有等到我服务端所有的报文都发送完了我才能发送 FIN 报文因此不能一起发送。故需要四次挥手。11.6、页面渲染浏览器渲染源代码解析HTML⽂档构造DOM树下载资源构造CSSOM树异步下载资源。只有构建完执⾏构造CSSOM树才会js脚本。12、keep-alive保存组件内容提高访问效率前端开发必备技能知识笔记-keep-alive路由缓存 - 知乎 (zhihu.com)keep-alive :include[routeA,routeB, ...] :max{{10}} :exclude[] router-view/router-view /keep-alive是始终将该组件保留在虚拟DOM中并且保持该组件以及后代组件的状态但是不渲染了