重温浏览器知识-同源策略
什么是同源策略,什么是跨域同源策略:protocol(协议)、domain(域名)、port(端口)三者必须一致。
同源政策主要限制了三个方面:
当前域下的 js 脚本不能够访问其他域下的 cookie、localStorage 和 indexDB。
当前域下的 js 脚本不能够操作访问操作其他域下的 DOM。
当前域下 ajax 无法发送跨域请求。
同源政策的目的主要是为了保证用户的信息安全,它只是对 js 脚本的一种限制,并不是对浏览器的限制,对于一般的 img、或者script 脚本请求都不会有跨域的限制,这是因为这些操作都不会通过响应结果来进行可能出现安全问题的操作。
什么是跨域
指的是浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的,是浏览器对 javascript 施加的安全限制,防止他人恶意攻击网站
跨域问题其实就是浏览器的同源策略造成的。
如何解决跨越问题CORSCORS需要浏览器和服务器同时支持,整个CORS过程都是浏览器完成的,无需用户参与。因此实现CORS的关键就是服务器,只要服务器实现了CORS请求,就可以跨源通信了。
JSONPjsonp的 ...
重温浏览器知识-浏览器存储
浏览器本地存储的方式Cookie
Cookie 是最早被提出来的本地存储方式,在此之前,服务端是无法判断网络中的两个请求是否是同一用户发起的,为解决这个问题,Cookie 就出现了。Cookie 的大小只有 4kb,它是一种纯文本文件,每次发起 HTTP 请求都会携带 Cookie。
Cookie 的特性:
Cookie 一旦创建成功,名称就无法修改
Cookie 是无法跨域名的,也就是说 a 域名和 b 域名下的 cookie 是无法共享的,这也是由 Cookie 的隐私安全性决定的,这样就能够阻止非法获取其他网站的 Cookie
每个域名下 Cookie 的数量不能超过 20 个,每个 Cookie 的大小不能超过 4kb
有安全问题,如果 Cookie 被拦截了,那就可获得 session 的所有信息,即使加密也于事无补,无需知道 cookie 的意义,只要转发 cookie 就能达到目的
Cookie 在请求一个新的页面的时候都会被发送过去
如果需要域名之间跨域共享 Cookie,有两种方法:
使用 Nginx 反向代理
在一个站点登陆之后,往其他网站写 Cookie。服 ...
重温浏览器知识-渲染
浏览器渲染过程中遇到 JS 文件如何处理?
JavaScript 的加载、解析与执行会阻塞文档的解析,也就是说,在构建 DOM 时,HTML 解析器若遇到了 JavaScript,那么它会暂停文档的解析,将控制权移交给 JavaScript 引擎,等 JavaScript 引擎运行完毕,浏览器再从中断的地方恢复继续解析文档。也就是说,如果想要首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因。当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性。
什么是文档的预解析?
Webkit 和 Firefox 都做了这个优化,当执行 JavaScript 脚本时,另一个线程解析剩下的文档,并加载后面需要通过网络加载的资源。这种方式可以使资源并行加载从而使整体速度更快。需要注意的是,预解析并不改变 DOM 树,它将这个工作留给主解析过程,自己只解析外部资源的引用,比如外部脚本、样式表及图片。
CSS 如何阻塞文档解析?
理论上,既然样式表不改变 DO ...
重温浏览器知识-通信缓存
如何实现浏览器内多个标签页之间的通信?
实现多个标签页之间的通信,本质上都是通过中介者模式来实现的。因为标签页之间没有办法直接通信,因此我们可以找一个中介者,让标签页和中介者进行通信,然后让这个中介者来进行消息的转发。通信方法如下:
使用 websocket 协议,因为 websocket 协议可以实现服务器推送,所以服务器就可以用来当做这个中介者。标签页通过向服务器发送数据,然后由服务器向其他标签页推送转发。
使用 ShareWorker 的方式,shareWorker 会在页面存在的生命周期内创建一个唯一的线程,并且开启多个页面也只会使用同一个线程。这个时候共享线程就可以充当中介者的角色。标签页间通过共享一个线程,然后通过这个共享的线程来实现数据的交换。
使用 localStorage 的方式,我们可以在一个标签页对 localStorage 的变化事件进行监听,然后当另一个标签页修改数据的时候,我们就可以通过这个监听事件来获取到数据。这个时候 localStorage 对象就是充当的中介者的角色。
使用 postMessage 方法,如果我们能够获得对应标签页的引用,就可 ...
重温浏览器知识-安全
什么可能引起前端安全问题?
跨站脚本 (Cross-Site Scripting, XSS): ⼀种代码注⼊⽅式, 为了与 CSS 区分所以被称作 XSS。早期常⻅于⽹络论坛, 起因是⽹站没有对⽤户的输⼊进⾏严格的限制, 使得攻击者可以将脚本上传到帖⼦让其他⼈浏览到有恶意脚本的⻚⾯, 其注⼊⽅式很简单包括但不限于 JavaScript / CSS / Flash 等;
iframe的滥⽤: iframe中的内容是由第三⽅来提供的,默认情况下他们不受控制,他们可以在iframe中运⾏JavaScirpt脚本、Flash插件、弹出对话框等等,这可能会破坏前端⽤户体验;
跨站点请求伪造(Cross-Site Request Forgeries,CSRF): 指攻击者通过设置好的陷阱,强制对已完成认证的⽤户进⾏⾮预期的个⼈信息或设定信息等某些状态更新,属于被动攻击
恶意第三⽅库: ⽆论是后端服务器应⽤还是前端应⽤开发,绝⼤多数时候都是在借助开发框架和各种类库进⾏快速开发,⼀旦第三⽅库被植⼊恶意代码很容易引起安全问题。
网络劫持有哪几种,如何防范?⽹络劫持分为两种:
DNS劫持: (输⼊京 ...
键盘行
键盘行
给你一个字符串数组 words ,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。美式键盘 中:第一行由字符 “qwertyuiop“ 组成。第二行由字符 “asdfghjkl“ 组成。第三行由字符 “zxcvbnm“ 组成。
输入:words = [“Hello”,”Alaska”,”Dad”,”Peace”]
输出:[“Alaska”,”Dad”]
1234567891011121314151617181920212223// 我们为每一个英文字母标记其对应键盘上的行号,然后检测字符串中所有字符对应的行号是否相同。// 我们可以预处理计算出每个字符对应的行号。// 遍历字符串时,统一将大写字母转化为小写字母方便计算。let findWords = function(words) { const list = []; const rowIdx = "12210111011122000010020202"; for (const word of words) { let isV ...
Nim 游戏
Nim 游戏
桌子上有一堆石头。你们轮流进行自己的回合, 你作为先手 。每一回合,轮到的人拿掉 1 - 3 块石头。拿掉最后一块石头的人就是获胜者。假设你们每一步都是最优解。请编写一个函数,来判断你是否可以在给定石头数量为 n 的情况下赢得游戏。如果可以赢,返回 true;否则,返回 false 。
输入:n = 4
输出:false
解释:以下是可能的结果:
移除 1 颗石头。你的朋友移走了 3 块石头,包括最后一块。你的朋友赢了。
移除 2 个石子。你的朋友移走 2 块石头,包括最后一块。你的朋友赢了。
你移走 3 颗石子。你的朋友移走了最后一块石头。你的朋友赢了。在所有结果中,你的朋友是赢家。
12345let canWinNim = function(n) { // 如果上来就踩到 4 的倍数,那就认输吧 // 否则,可以把对方控制在 4 的倍数,必胜 return n % 4 !== 0;};
同构字符串
同构字符串
给定两个字符串 s 和 t ,判断它们是否是同构的。如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。
输入:s = “egg”, t = “add”
输出:true
1234567891011121314let isIsomorphic = function(s, t) { const s2t = {}; const t2s = {}; const len = s.length; for (let i = 0; i < len; ++i) { const x = s[i], y = t[i]; if ((s2t[x] && s2t[x] !== y) || (t2s[y] && t2s[y] !== x)) { r ...
在排序数组中查找元素的第一个和最后一个位置
在排序数组中查找元素的第一个和最后一个位置
给一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。设计并实现时间复杂度为 O(log n) 的算法解决此问题。
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
123456789101112131415161718192021222324// 二分法const binarySearch = (nums, target, lower) => { let left = 0, right = nums.length - 1, ans = nums.length; while (left <= right) { const mid = Math.floor((left + right) / 2); if (nums[mid] > target || (lower && nums ...
颜色分类
颜色分类
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。必须在不使用库内置的 sort 函数的情况下解决这个问题。
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
12345678910111213141516171819202122232425// 0、 1 和 2 分别表示红色、白色和蓝色。// 我们可以设置 3 个指针,一个指向头部,一个指向尾部,还有一个指向当前遍历的元素。// 我们从头部开始遍历数组,如果遇到 0(红色)就把它放到头部指针的位置,// 如果遇到 2(蓝色)就把它放到尾部指针的位置。// 如果遇到 1(白色),就跳过它,继续遍历。var sortColors = function(nums) { let left = 0; let right = nums.length - 1; for (let i = 0; i <= right; i++) ...