xml地图|网站地图|网站标签 [设为首页] [加入收藏]
代码保护,不要再问我跨域的问题了
分类:web前端

实例解析防抖动和节流阀

2016/04/26 · JavaScript · DOM

本文由 伯乐在线 - 涂鸦码龙 翻译。未经许可,禁止转载!
英文出处:css-tricks。欢迎加入翻译组。

防抖(Debounce)和节流(throttle)都是用来控制某个函数在一定时间内执行多少次的技巧,两者相似而又不同。

当我们给 DOM 绑定事件的时候,加了防抖和节流的函数变得特别有用。为什么呢?因为我们在事件和函数执行之间加了一个控制层。记住,我们是无法控制 DOM 事件触发频率的。

看下滚动事件的例子:

See the Pen Scroll events counter by Corbacho (@dcorb) on CodePen.

当使用触控板,滚动滚轮,或者拖拽滚动条的时候,一秒可以轻松触发30次事件。经我的测试,在智能手机上,慢慢滚动一下,一秒可以触发事件100次之多。这么高的执行频率,你的滚动回调函数压力大吗?

早在2011年,Twitter 网站抛出了一个问题:向下滚动 Twitter 信息流的时候,变得很慢,很迟钝。John Resig 发表了一篇博客解释这个问题,文中解释到直接给 scroll 事件关联昂贵的函数,是多么糟糕的主意。

John(5年前)建议的解决方案是,在 onScroll 事件外部,每 250ms 循环执行一次。简单的技巧,避免了影响用户体验。

现如今,有一些稍微高端的方式处理事件。我来结合用例介绍下 Debounce,Throttle 和 requestAnimationFrame 吧。

可信前端之路-代码保护

2016/09/11 · CSS, JavaScript · 安全

原文出处: 莫念@阿里安全   

不要再问我跨域的问题了

2018/07/16 · 基础技术 · 跨域

原文出处: 写Bug   

写下这篇文章后我想,要不以后就把这种基础的常见知识都归到这个“不要再问我XX的问题”,形成一系列内容,希望大家看完之后再有人问你这些问题,你心里会窃喜:“嘿嘿,是时候展现真正的技术了!”
一、不要再问我this的指向问题了

跨域这两个字就像一块狗皮膏药一样黏在每一个前端开发者身上,无论你在工作上或者面试中无可避免会遇到这个问题。为了应付面试,我每次都随便背几个方案,也不知道为什么要这样干,反正面完就可以扔了,我想工作上也不会用到那么多乱七八糟的方案。到了真正工作,开发环境有webpack-dev-server搞定,上线了服务端的大佬们也会配好,配了什么我不管,反正不会跨域就是了。日子也就这么混过去了,终于有一天,我觉得不能再继续这样混下去了,我一定要彻底搞懂这个东西!于是就有了这篇文章。

防抖动(Debounce)

防抖技术可以把多个顺序地调用合并成一次。

图片 1

假想一下,你在电梯中,门快要关了,突然有人准备上来。电梯并没有改变楼层,而是再次打开梯门。电梯延迟了改变楼层的功能,但是优化了资源。

在顶部按钮上点击或移动鼠标试一下:

See the Pen Debounce. Trailing by Corbacho (@dcorb) on CodePen.

你可以看到连续快速的事件是如何被一个 debounce 事件替代的。但是如果事件触发的时间间隔过长,debounce 则不会生效。

0x00 前言

在信息安全领域,可信系统(Trusted system)是一个让人心动的目标,它指的是一个通过实施特定的安全策略而达到一定可信程度的系统。

在计算机中,可信平台模块(Trusted Platform Module,TPM)已经投入使用,它符合可信赖计算组织(Trusted Computing Group,TCG)制定的TPM规范,是为了实现可信系统目标的而打造的一款安全芯片。作为可信系统的信任根,TPM是可信计算的核心模块,为计算机安全提供了强有力的保障。

图片 2

而在我们的web系统中,想打造一个可信系统似乎是个伪命题,”永远不要相信客户端的输入”是基本的安全准则。实际上,在可信系统中的可信也并不是说真的是绝对安全,维基上对其的解释为:“可信的”(Trusted)未必意味着对用户而言是“值得信赖的”(Trustworthy)。确切而言,它意味着可以充分相信其行为会更全面地遵循设计,而执行设计者和软件编写者所禁止的行为的概率很低。

从这个角度讲,我们把其当做一个美好的愿景,我们希望能够构造一个web系统中的TPM,可以把恶意行为控制在一定的概率之内,从而实现一个相对可信的web系统。

要掌握跨域,首先要知道为什么会有跨域这个问题出现

确实,我们这种搬砖工人就是为了混口饭吃嘛,好好的调个接口告诉我跨域了,这种阻碍我们轻松搬砖的事情真恶心!为什么会跨域?是谁在搞事情?为了找到这个问题的始作俑者,请点击浏览器的同源策略。
这么官方的东西真难懂,没关系,至少你知道了,因为浏览器的同源策略导致了跨域,就是浏览器在搞事情。
所以,浏览器为什么要搞事情?就是不想给好日子我们过?对于这样的质问,浏览器甩锅道:“同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。”
这么官方的话术真难懂,没关系,至少你知道了,似乎这是个安全机制。
所以,究竟为什么需要这样的安全机制?这样的安全机制解决了什么问题?别急,让我们继续研究下去。

前缘(或者“immediate”)

你会发现,直到事件停止快速执行以后,debounce 事件才会触发相应功能。为何不立即触发呢?那样的话就跟原本的非 debounce 处理无异了。 直到两次快速调用之间的停顿结束,事件才会再次触发。

这是带 leading 标记的例子:

图片 3

前缘 debounce 的例子 在 underscore.js 中,选项叫 immediate ,而不是 leading:

See the Pen Debounce. Leading by Corbacho (@dcorb) on CodePen.

0x01 可信前端

在可信系统中,TPM的一个重要作用就是鉴别消息来源的真实性,保障终端的可信。在web系统中,我们的消息来源就是用户。随着撞库、恶意注册、薅羊毛等产业的蓬勃发展,在越来越多的场景我们需要鉴别请求数据是否来自真实的用户,保护真实用户的数据安全。

所以想要构造一个web系统中的TPM,首要问题就是需要保证输入数据安全,打造一个相对可信的前端环境。但是由于web的开放特性,前端作为数据采集的最前线,js代码始终暴露在外,在这种情况下,防止恶意伪造请求变得非常困难,可信前端也就成了无稽之谈。

在反复对抗中,代码保护也就是通常意义上的js代码混淆的重要性逐渐彰显出来。今天我就想和大家聊一聊js混淆的问题。

没有同源策略限制的两大危险场景

据我了解,浏览器是从两个方面去做这个同源策略的,一是针对接口的请求,二是针对Dom的查询。试想一下没有这样的限制上述两种动作有什么危险。

Debounce 实现

我首次看到 debounce 的 JavaScript 实现是在 2009 年的 John Hann 的博文。

不久后,Ben Alman 做了个 jQuery 插件(不再维护),一年后 Jeremy Ashkenas 把它加入了 underscore.js 。而后加入了 Lodash 。

See the Pen New example by Corbacho (@dcorb) on CodePen.

Lodash 给 _.debounce 和 _.throttle 添加了不少特性。之前的 immediate 被 leading(最前面) 和 trailing(最后面) 选项取代。你可以选一种,或者都选,默认只有 trailing 启用。

新的 maxWait 选项(仅 Lodash 有)本文未提及,但是也很有用。事实上,throttle 方法是用 _.debounce 加 maxWait 实现的,你可以看 lodash 源码 。

1、为什么需要js混淆

显而易见,是为了保护我们的前端代码逻辑。

在web系统发展早期,js在web系统中承担的职责并不多,只是简单的提交表单,js文件非常简单,也不需要任何的保护。

随着js文件体积的增大,为了缩小js体积,加快http传输速度,开始出现了很多对js的压缩工具,比如 uglify、compressor、clouser。。。它们的工作主要是

    · 合并多个js文件

    · 去除js代码里面的空格和换行

    · 压缩js里面的变量名

    · 剔除掉注释

图片 4

压缩后的代码

虽然压缩工具出发点都是为了减少js文件的体积,但是人们发现压缩替换后的代码已经比源代码可读性差了很多,间接起到了代码保护的作用,于是压缩js文件成为了前端发布的标配之一。但是后来市面上主流浏览器chrome、Firefox等都提供了js格式化的功能,能够很快的把压缩后的js美化,再加上现代浏览器强大的debug功能,单纯压缩过的js代码对于真正怀有恶意的人,已经不能起到很好的防御工作,出现了”防君子不防小人”的尴尬局面。

图片 5

chrome开发者工具格式化之后的代码

而在web应用越来越丰富的今天,伴随着浏览器性能和网速的提高,js承载了更多的工作,不少后端逻辑都在向前端转移,与此同时也让更多的不法分子有机可乘。在web模型中,js往往是不法分子的第一个突破口。知晓了前端逻辑,不法分子可以模拟成一个正常的用户来实施自己的恶意行为。所以,在很多登录、注册、支付、交易等等页面中,关键业务和风控系统依赖的js都不希望被人轻易的破解,js混淆应运而生。

没有同源策略限制的接口请求

有一个小小的东西叫cookie大家应该知道,一般用来处理登录等场景,目的是让服务端知道谁发出的这次请求。如果你请求了接口进行登录,服务端验证通过后会在响应头加入Set-Cookie字段,然后下次再发请求的时候,浏览器会自动将cookie附加在HTTP请求的头字段Cookie中,服务端就能知道这个用户已经登录过了。知道这个之后,我们来看场景:
1.你准备去清空你的购物车,于是打开了买买买网站www.maimaimai.com,然后登录成功,一看,购物车东西这么少,不行,还得买多点。
2.你在看有什么东西买的过程中,你的好基友发给你一个链接www.nidongde.com,一脸yin笑地跟你说:“你懂的”,你毫不犹豫打开了。
3.你饶有兴致地浏览着www.nidongde.com,谁知这个网站暗地里做了些不可描述的事情!由于没有同源策略的限制,它向www.maimaimai.com发起了请求!聪明的你一定想到上面的话“服务端验证通过后会在响应头加入Set-Cookie字段,然后下次再发请求的时候,浏览器会自动将cookie附加在HTTP请求的头字段Cookie中”,这样一来,这个不法网站就相当于登录了你的账号,可以为所欲为了!如果这不是一个买买买账号,而是你的银行账号,那……
这就是传说中的CSRF攻击浅谈CSRF攻击方式。
看了这波CSRF攻击我在想,即使有了同源策略限制,但cookie是明文的,还不是一样能拿下来。于是我看了一些cookie相关的文章聊一聊 cookie、Cookie/Session的机制与安全,知道了服务端可以设置httpOnly,使得前端无法操作cookie,如果没有这样的设置,像XSS攻击就可以去获取到cookieWeb安全测试之XSS;设置secure,则保证在https的加密通信中传输以防截获。

Debounce 实例

调整大小的例子

调整桌面浏览器窗口大小的时候,会触发很多次 resize 事件。 看下面 demo:

See the Pen Debounce Resize Event Example by Corbacho (@dcorb) on CodePen.

如你所见,我们为 resize 事件使用了默认的 trailing 选项,因为我们只关心用户停止调整大小后的最终值。

基于 AJAX 请求的自动完成功能,通过 keypress 触发

为什么用户还在输入的时候,每隔50ms就向服务器发送一次 AJAX 请求?_.debounce 可以帮忙,当用户停止输入的时候,再发送请求。

此处也不需要 leading 标记,我们想等最后一个字符输完。

See the Pen Debouncing keystrokes Example by Corbacho (@dcorb) on CodePen.

相似的使用场景还有,直到用户输完,才验证输入的正确性,显示错误信息。

2、js混淆是不是纸老虎

这是一个老生常谈的问题。实际上,代码混淆早就不是一个新鲜的名词,在桌面软件时代,大多数的软件都会进行代码混淆、加壳等手段来保护自己的代码。Java和.NET都有对应的混淆器。黑客们对这个当然也不陌生,许多病毒程序为了反查杀,也会进行高度的混淆。只不过由于js是动态脚本语言,在http中传输的就是源代码,逆向起来要比打包编译后的软件简单很多,很多人因此觉得混淆是多此一举。

图片 6

.NET混淆器dotFuscator

其实正是因为js传输的就是源代码,我们才需要进行混淆,暴露在外的代码没有绝对的安全,但是在对抗中,精心设计的混淆代码能够给破坏者带来不小的麻烦,也能够为防守者争取更多的时间,相对于破解来说,混淆器规则的更替成本要小得多,在高强度的攻防中,可以大大增加破解者的工作量,起到防御作用。从这个角度来讲,关键代码进行混淆是必不可少的步骤。

没有同源策略限制的Dom查询

1.有一天你刚睡醒,收到一封邮件,说是你的银行账号有风险,赶紧点进www.yinghang.com改密码。你吓尿了,赶紧点进去,还是熟悉的银行登录界面,你果断输入你的账号密码,登录进去看看钱有没有少了。
2.睡眼朦胧的你没看清楚,平时访问的银行网站是www.yinhang.com,而现在访问的是www.yinghang.com,这个钓鱼网站做了什么呢?

// HTML <iframe name="yinhang" src="www.yinhang.com"></iframe> // JS // 由于没有同源策略的限制,钓鱼网站可以直接拿到别的网站的Dom const iframe = window.frames['yinhang'] const node = iframe.document.getElementById('你输入账号密码的Input') console.log(`拿到了这个${node},我还拿不到你刚刚输入的账号密码吗`)

1
2
3
4
5
6
7
// HTML
<iframe name="yinhang" src="www.yinhang.com"></iframe>
// JS
// 由于没有同源策略的限制,钓鱼网站可以直接拿到别的网站的Dom
const iframe = window.frames['yinhang']
const node = iframe.document.getElementById('你输入账号密码的Input')
console.log(`拿到了这个${node},我还拿不到你刚刚输入的账号密码吗`)

由此我们知道,同源策略确实能规避一些危险,不是说有了同源策略就安全,只是说同源策略是一种浏览器最基本的安全机制,毕竟能提高一点攻击的成本。其实没有刺不穿的盾,只是攻击的成本和攻击成功后获得的利益成不成正比。

本文由澳门新葡亰手机版发布于web前端,转载请注明出处:代码保护,不要再问我跨域的问题了

上一篇:高效快速地加载,不适合复杂的前端项目 下一篇:没有了
猜你喜欢
热门排行
精彩图文