写代码啦

为什么不建议将 font-size 设置为 12px 以下

ta 的热文

为什么不建议将 font-size 设置为 12px 以下

问题:为什么不建议将 font-size 设置为 12px 以下?如果一定要设置为 12px 以下要怎么做? 先看看把 font-size 设置为 12px 以下时的效果:(浏览器为 Chrome 52) https://ooo.0o0.ooo/2017/06/15/59423fa56d96a.png 在其他浏览器上效果却不一样: https://ooo.0o0.ooo/2017/06/15/59424004139e5.png 因为 Chrome 这款任性的浏览器做了如下限制: font-size 有一个最小值 12px(不同操作系统、不同语言可能限制不一样),低于 12px 的,一律按 12px 显示。理由是 Chrome 认为低于 12px 的中文对人类是不友好的。 但是允许你把 font-size 设置为 0. 这个 12px 的限制用户是可以自行调整的,进入 chrome://settings/fonts 设置,滚动到最下方你就可以调整 12px 为其他值。 https://ooo.0o0.ooo/2017/06/15/594240616ed4b.png 如果我一定要设置小于 12px 的字体怎么办? Chrome 29 版本之前,你可以使用 -webkit-text-size-adjust: none; 来解除这个限制。29 版本后,就不能这样做了。 你可以先设置 12px,然后使用 transform: scale(0.833333) 将元素缩小,效果跟 10px 很接近。不过要注意的是,transform: scale 出了缩小 font-size,也会缩小其他一些属性,需要多测试。 作者:方应杭 (http://www.zhihu.com/people/zhihusucks/answers), 想学前端?进群 (http://qr.jirengu.com/api/taskUrl?tid=1)
 1138 ·  07月31日 11:35
blog

CSRF 是什么?

先从一个故事说起(故事纯属虚构,恶意模仿后果自负): 小谷最近遭遇电信诈骗被骗的倾家荡产,于是他想到了报复社会。在知乎上狂点800个没有帮助1000个举报后,他决定做点正事干票捞钱的生意。 「很多视频网站都有赠送礼品的功能,假如所有人都赠送我个礼物,我再转卖掉,不就发财啦」小谷寻思着。 说干就敢,经过一番折腾测试,小谷发现视频网站赠送礼物的接口是: https://xxxx.com/gift/send?target=someone&giftId=ab231 , 原来只要用户在登录状态下请求这个地址,就能给名为someone的用户赠送礼品ab231。 那如何才能让其他用户请求这个接口呢?其实只要用户点击就行,「色诱是最好的陷阱」回想起自己被骗的经过,小谷猥琐狠狠的打了一行文字 ——「想要的都在这里,今夜注定让你无眠~~ 饥人谷-最有爱的前端学习社区 (http://jirengu.com/)」,然后在各个群组里回复。 经过一天等待,有几个上钩的,但远远达不到预期,「有没有更自动的办法,让用户只要看到即使不点也能上钩呢?」。小谷开始对整个网站功能逐一过滤,突然他眼前一亮,在用户评论编辑框内看到了上传外链图片的功能。「如果把这个 url 作为图片填进去,上传后会在评论区创建一个img 标签,src 对应的就是这个地址。当用户打开页面后这个 img 就会自动加载图片也就是发送这个请求,这样一来凡是打开这个页面的人不论是不是点击这个链接都会给赠送礼物,perfect!」 小谷为自己的聪明才智惊叹。 又过了一天,果然源源不断的礼物送了过来。这个时候小谷隐隐有些担心起来,虽然礼物送的都很小,但赠送都是有历史记录的,用户查看历史记录肯定会起疑心,能不能帮用户删除这条赠送记录呢?经过测试,发现删除赠送记录的接口地址是 https://xxxx.com/gift/deleteRecord , 接口类型为POST,请求参数为 { giftId:"ab231"}。 用户无法通过点击一个链接在不知情的情况下发送 POST 请求,怎么办呢?于是,小谷构造了一个页面: ``` 哈哈,给你开了个玩笑,莫生气~ document.getElementById('form').submit(); location.href = "http://xxxx.com"; ``` 当用户点开这个页面的链接后,会自动发送 POST 请求,然后跳转到原始首页。这样用户既在不知情的情况下赠送了礼品,又在不知情的情况下删除了赠送记录。大功告成后,小谷购买了个广告机在各大论坛狂发.... 一周之后,警察👮叔叔来敲门了,咚🕳🕳 上面小谷的攻击流程就是典型的 CSRF (Cross Site Request Forgery)攻击,中文名:跨站请求伪造。其原理是攻击者构造网站后台某个功能接口的请求地址,诱导用户去点击或者用特殊方法让该请求地址自动加载。用户在登录状态下这个请求被服务端接收后会被误以为是用户合法的操作。对于 GET 形式的接口地址可轻易被攻击,对于 POST 形式的接口地址也不是百分百安全,攻击者可诱导用户进入带 Form 表单可用POST方式提交参数的页面。 后续...... xxxx视频网站不断接到用户举报,自己的礼品莫名丢失。经过排查发现有攻击者利用 CSRF 进行攻击,报警后赶紧让公司的安全部门的小饥来修复漏洞。 小饥梳理了一遍公司网站所有的接口,发现很多接口都存在这个问题。于是采用了anti-csrf-token的方案。 具体方案如下: 服务端在收到路由请求时,生成一个随机数,在渲染请求页面时把随机数埋入页面(一般埋入 form 表单内,) 服务端设置setCookie,把该随机数作为cookie或者session种入用户浏览器 当用户发送 GET 或者 POST 请求时带上csrftoken参数(对于 Form 表单直接提交即可,因为会自动把当前表单内所有的 input 提交给后台,包括csrftoken) 后台在接受到请求后解析请求的cookie获取csrftoken的值,然后和用户请求提交的csrftoken做个比较,如果相等表示请求是合法的。 https://ooo.0o0.ooo/2017/06/19/594788ec88c03.jpeg https://ooo.0o0.ooo/2017/06/19/5947890316b95.jpeg (上图是某电商网站的真实设置,这里页面上设置的 token和session里设置的token 虽然不直接相等,但 md5('1474357164624') === '4bd4e512b0fbd9357150649adadedd4e',后台还是很好计算的) 安全部的Leader 看了看小饥的方案,「方案出的很赞, 不过还有几点需要注意一下」: Token 保存在 Session 中。假如 Token 保存在 Cookie 中,用户浏览器开了很多页面。在一些页面 Token 被使用消耗掉后新的Token 会被重新种入,但那些老的 Tab 页面对应的 HTML 里还是老 Token。这会让用户觉得为啥几分钟前打开的页面不能正常提交? 尽量少用 GET。假如攻击者在我们的网站上传了一张图片,用户在加载图片的时候实际上是向攻击者的服务器发送了请求,这个请求会带有referer表示当前图片所在的页面的 url。 而如果使用 GET 方式接口的话这个 URL 就形如: https://xxxx.com/gift?giftId=aabbcc&_csrf_token=xxxxx ,那相当于攻击者就获取了csrftoken,短时间内可以使用这个 token 来操作其他 GET 接口。 「这个项目,就由你来推动实施,晚上加加班争取这两天搞定~」 作者:若愚 (http://www.zhihu.com/people/jirengu-ruo-yu/answers),想学前端?进群 (http://qr.jirengu.com/api/taskUrl?tid=1)
 724 ·  07月31日 15:04
blog

谈谈你对原型、原型链、 Function、Object 的理解?

本文讲解了原型、原型链、 Function、Object 之间的关系 问题 有如下代码: ``` //代码1 function People(){} var p = new People() p.proto === People.prototype People.proto === Function.prototype People.prototype.proto === Object.prototype //代码2 Function.prototype === Function.proto Function.prototype === Object.proto Function.prototype.proto === Object.prototype Function instanceof Object //代码3 Object instanceof Function Function instanceof Object Function instanceof Function Object instanceof Object ``` 问题1:画出代码1的原型图? 问题2:从代码2你能得出什么结论?试画出原型图? 问题3:解释代码3的原因? 解答: 在解答上面的问题之前,先记住下面几句话,这几句话能解释一切关于原型方面的问题: 当 new 一个函数的时候会创建一个对象,『函数.prototype』 等于 『被创建对象.__proto__』 一切函数都是由 Function 这个函数创建的,所以『Function.prototype === 被创建的函数.__proto__』 一切函数的原型对象都是由 Object 这个函数创建的,所以『Object.prototype === 一切函数.prototype.__proto__』 下面是代码1的原型图: https://ooo.0o0.ooo/2017/06/19/59478004a82eb.jpg (1)People函数创建了对象 p,所以People.prototype === p.__proto__; (2)Object函数创建了People.prototype对象,所以Object.prototype === People.prototype.__proto__; (3)People 作为对象的角色被函数Function创建,所以 Function.prototype === People.__proto__ 下面是代码2的原型图: https://ooo.0o0.ooo/2017/06/19/5947803edb010.jpg (1)任何函数都是 Function 创建,所以Function 创建了 Function,所以 Function.prototype === Function.__proto__; (2)Object 也是函数。所以Function创建了Object,所以 Function.prototype === Object.__proto__; (3)Function.prototype 是普通对象,普通对象是由Object创建的,所以Function.prototype.__proto__ === Object.prototype 关于代码3: instanceof 的作用是判断一个对象是不是一个函数的实例。比如 obj instanceof fn, 实际上是判断fn的prototype是不是在obj的原型链上。比如:obj.__proto__ === fn.prototype,obj.__proto__.__proto__ === fn.prototype,obj.__proto__..._proto__ === fn.prototype,只要一个成立即可。 所以(根据图2来找) 对于 Function instanceof Function,因为 Function.__proto__ === Function.prototype,所以为true。 对于 Object instanceof Object, 因为 Object.__proto__.__proto__ === Function.prototype.__proto__ === Object.prototype , 所以为true 对于 Function instanceof Object, 因为 Function.__proto__.__proto__ === Function.prototype.__proto__ === Object.prototype, 所以为 true 对于 Object instanceof Function, 因为 Object.__proto__ === Function.prototype,所以为 true 至此,问题全被完美解决。 想学前端?进群 (http://qr.jirengu.com/api/taskUrl?tid=1)
 664 ·  07月31日 15:37
blog