写代码啦

若愚 老师

饥人谷前端讲师,亲手送数千工程师进入前端行业。前大厂程序员,善于把复杂的问题讲简单。

我的授课 Ta 的授课

我的课程 Ta 的课程

实现简易Webpack
实现一套移动端手势库
实现简易jQuery
新版·前端体系班(2位老师带班)
《新 • 前端体系课》第72期
Promise专题(系统班专享)
彻底搞定 Promise的一切(大厂/15K求职面试必考知识点)
静态页面实战合集
React入门原理+实战
Webpack Loader 与Plugin的实现
前端入门训练营(第4期)
CSS3、JavaScript 入门项目—实现酷炫虚拟键盘
Vue3精简版(若愚版)
Vue3从入门到精通
前端剑指offer(CSS、移动端、HTTP主题)
使用Node.js实现Webpack
小程序云开发
100天前端冲刺提升班
前端面试刷题
React 项目实战之epic图床
OneSlide项目实战
在线简历制作(速成版)
前端体系课【若愚】
前端面试知识点专项突破——HTML、CSS专题
原生JS造轮子系列
移动端开发
前端&Java求职面试指导
原生JavaScript开发华为音乐
JS设计模式(JavaScript)
HTTP深入浅出
一款多语言chrome划词翻译插件
SVG速学
小程序开发翻译工具
CSS布局适配大全
静态页面知识点大全
趣谈前端
Vue.js实现多人共享博客
前端公开课
手写一个简易 Vue 框架
Vue.js开发印象云笔记
前端面试核心知识汇总
移动端豆瓣电影项目
Node Express.js在线备忘录
手写一个简易 Express 框架
前端系统班:每周拓展直播
FM音乐播放器
从入门到工作-若愚

我的项目

Ta 的项目

{{project.name}}  {{project.view_count}}
加载更多

我的文章

Ta 的文章

HTML、CSS、Javascript前世今生

HTML、CSS、Javascript 的历史 1980年,欧洲核子研究中心(CERN)工作的物理学家蒂姆·伯纳斯 - 李(Tim Berners-Lee)提出了原型INQUIRE,这是一个供欧洲核子研究中心研究人员使用和共享文件的系统。 1989年,伯纳斯 - 李写了一份备忘录,提出了一个基于互联网的超文本系统。Berners-Lee在1990年对HTML进行了描述,并编写了浏览器和服务器。在1990年的个人笔记中,他列出了“一些能使用超文本的领域”并首先放入了百科全书。 第一个公开提供的HTML描述是1991年末Tim Berners-Lee在互联网上提到的一个名为“HTML标签”的文档。除了超链接标记,它们受到SGML 风格的强烈影响,SGML (https://en.wikipedia.org/wiki/Standard_Generalized_Markup_Language)是CERN内部基于标准通用标记语言的文档格式。1993年中期出版了第一个HTML规范提案。在HTML和HTML +草案于1994年初到期之后,IETF (https://en.wikipedia.org/wiki/Internet_Engineering_Task_Force)(Internet Engineering Task Force,互联网工程任务组)创建了一个HTML工作组,该工作组在1995年完成了“HTML 2.0”,这是第一个HTML规范,旨在作为未来实现应该基于的标准。 随着HTML的发展,它开始涵盖更广泛的风格功能,以满足Web开发人员的需求。这种演变使设计师能够以更复杂的HTML为代价更好地控制网站外观。 由Tim Berners-Lee开发的浏览器/编辑器具有硬编码到程序中的样式表。但样式表不能链接到网络上的文件。欧洲核子研究中心的Robert Cailliau希望将结构与演示文稿分开,以便不同的样式表可以描述不同的打印,基于屏幕的演示文稿和编辑的演示文稿。改进网络演示功能是网络社区中许多人感兴趣的主题,在给出的提案中,有两个对CSS成为特别有影响力:级联HTML样式表和基于流的样式表提案(SSP)。 Håkon Wium Lie (CSS 的发明者,Tim Berners-Lee 的同事)与Yves Lafon合作,在Arena浏览器中实现CSS。Bert Bos在Argo浏览器中实施了自己的SSP提案。后来,Lie和Bos共同开发了CSS标准。 Lie的提议于1994年在伊利诺伊州芝加哥举行的“Mosaic and the Web”会议(后来称为WWW2)上提出,并于1995年再次与Bert Bos一同提出。大约在这个时候,W3C已经建立,并且对CSS的开发感兴趣。它组织了一个由Steven Pemberton主持的研讨会。这导致W3C将CSS工作添加到HTML编辑审查委员会(ERB)的可交付成果中。到1996年底,CSS level1于12月官方发布。 1993年,伊利诺伊大学的国家超级计算应用中心(NCSA)发布了NCSA Mosaic,这是第一个流行的图形Web浏览器。 1994年,一家名为Mosaic Communications的公司在加利福尼亚州成立,并聘请了许多NCSA Mosaic原始开发团队的工程师创建Mosaic Netscape。该公司浏览器的内部代号为Mozilla,代表“Mosaic杀手”,因为该公司的目标是取代NCSA Mosaic成为世界第一的网络浏览器。第一个版本的Web浏览器Mosaic Netscape 0.9于1994年底发布。在四个月内,它已经占据了浏览器市场的四分之三,并成为20世纪90年代互联网的主要浏览器。为避免NCSA的商标所有权问题,该浏览器于同年更名为Netscape Navigator,该公司也改名为Netscape Communications。 Netscape公司意识到Web需要变得更加动态。该公司的创始人Marc Andreessen认为HTML需要一种“胶水语言”,Web设计人员和兼职程序员可以轻松地使用它来组装图像和插件等组件,其中代码可以直接在Web页面中编写标记。 1995年,Netscape Communications招聘Brendan Eich,目标是将Scheme编程语言嵌入到Netscape Navigator中。在他开始之前,Netscape Communications与Sun Microsystems合作,在Netscape Navigator Sun中使用更为静态的编程语言Java,以便与微软竞争用户采用Web技术和平台。然后Netscape Communications决定他们想要创建的脚本语言将补充Java,并且应该有类似的语法,排除采用其他语言,如Perl,Python,TCL或Scheme。Eich于1995年5月花了10天时间实现了一种语言Mocha。公司觉得这么名字不够霸气,在1995年9月首次发布Netscape Navigator 2.0测试版时正式改为称为LiveScript。当时 Java 作为后端语言很火,在12月份部署在Netscape Navigator 2.0 beta 3中时,LiveScript它被重命名为JavaScript。这样会让普通人误以为JavaScript和 Java 是近亲。幻想一下,现在有 Node.js,假设有人出个 NodeScript,不明真相的吃瓜群众肯定以为是下一代 Node。 浏览器大战 技术和产品的诞生是鸡生蛋蛋生鸡的关系,讲 HTML、CSS、JavaScript 的起源不得不提到浏览器大战。 到1992年底,已经出现了不少浏览器,这些浏览器大都是基于libwww库,尽管这些浏览器往往是简单的HTML查看器,依靠外部帮助应用程序来查看多媒体内容,但它们为浏览器和平台上的用户提供了选择。 1993年更多浏览器发布,其中最有影响力的是前面提到的Mosaic,它是 NCSA开发的多平台图形界面浏览器。到1994年10月,Mosaic 成为浏览器人气王。 Mosaic的其中一位开发者Marc Andreessen,作为联合创始人创立了Mosaic Communications 公司,开发了一款名为Mosaic Netscape的新浏览器。 按照当时的说法,互联网有两个时代 :Mosaic之前和Mosaic之后。Tim Berners-Lee的Web协议提供端到端的链接,Marc Andreesen的 Mosaic浏览器提供舒适的图形界面。事实证明这两种组合产生的效果是爆炸性的。仅仅24个月,互联网从从未知到无处不在。 后来为解决NCSA的法律问题,该公司更名为Netscape Communications 公司,产品也更名为Netscape Navigator浏览器。 Netscape浏览器改进了Mosaic的可用性和可靠性,并能够在加载时显示页面。到1995年,由于它可以免费用于非商业用途,浏览器主导了新兴的万维网。 第一次浏览器大战——棋逢对手 到1995年中期,万维网在大众文化和大众媒体中受到了极大的关注。 Netscape Navigator变成使用最广泛的网络浏览器。但是狼来了。 微软获得 Mosaic 的授权,创建Internet Explorer 1.0,它已作为Microsoft Windows 95 的一部分于8月打包发布。而此时微软已经成为最受欢迎的桌面系统。 三个月后,Internet Explorer 2.0以免费下载的形式发布。与Netscape Navigator不同,它可供所有Windows用户免费使用,甚至是商业公司。微软的行为也迫使其他浏览器公司只能跟随并免费提供他们的浏览器。 1997年10月,Internet Explorer 4.0发布。Internet Explorer 4改变了浏览器之战的潮流。它被集成到Microsoft Windows 系统中,导致份额暴涨。 这时候,第一次真正出现了浏览器兼容的问题。在不同版本中,Web设计人员通常会显示“在Netscape中查看最佳”或“在Internet Explorer中查看最佳”徽标。这些图像通常标识特定的浏览器版本,并且通常链接到可以从其下载所述浏览器的源。然而,大多数主流网站都将Netscape或IE中的一个指定为首选浏览器,同时尝试支持最小功能。开发者和用户不干了,标准统一迫在眉睫。 大战的解决显而易见,微软大获全胜, 第二次浏览器大战——新秀崛起 Navigator在第一次浏览器大战的中间阶段就预测了大战的结局。于是在公司开始衰落之初,Netscape开源了他们的浏览器代码,后来委托给新成立的非营利性Mozilla基金会 ——一个主要由社区驱动的项目,给 Netscape 保留香火。之后 Netscape 作为两个分支来开发,一个是 Netscape,一个是Firefox。开发持续了几年,但人气一直很弱,直到后来Mozilla Firefox 1.0的发布(2004年11月)。之后Firefox开始慢慢在浏览器市场中获得越来越大的份额,直到2010年达到顶峰。 Opera在浏览器大战中一直是一个小玩家,该浏览器引入标签式浏览和鼠标手势等创新功能,以及轻量级但功能丰富而著称。 2006年6月,Opera Software发布了Opera 9,之后发布一款口碑还不错的移动浏览器Opera Mini。 微软与2001年发布了 IE6,一直流行了10年。2006年10月IE7发布,内置于Windows Vista系统中。2009年发布 IE8,内置在 windows 8系统中。2011年发布IE9,没内置系统,IE9只支持Windows Vista SP2及Windows 7。15年发布Edge,成为 windows10的默认浏览器。 2006,Mozilla发布了Mozilla Firefox 2.0。2008发布了Firefox 3.0。 Firefox 3.5于2009年6月30日推出。 Apple在2002年创建了开源KHTML和KJS布局以及JavaScript引擎的分支。最终的布局引擎被称为WebKit,它被整合到最初随Mac OS X v10.3一起提供的Safari浏览器中。 谷歌于2008年12月发布了适用于Microsoft Windows的Chrome浏览器,使用与Safari相同的WebKit渲染引擎和一个名为V8的更快的JavaScript引擎。不久之后,以Chromium的名义发布了Windows,OS X和Linux平台的开源版本。 HTML、CSS、JavaScript 版本 HTML 版本 1991年10月 HTML列出了18个HTML标签,在公开场合被提到的。 1995年11月24日 HTML 2.0 发布,增加了如基于表单的文件上传等功能 1995年4月 HTML 3.0 被提议作为IETF的标准,但失败了。原因:太过复杂、浏览器大战 1997年1月14日 HTML 3.2 作为W3C推荐标准发布,这是由W3C独家开发和标准化的第一个版本 1997年12月18日 HTML 4.0 作为W3C推荐标准发布 1999年12月24日 HTML 4.01 作为W3C推荐标准发布,在HTML5之前大家学的 HTML 都是这个版本 2014年10月28日 HTML5 (2016年HTML5.1, 2017年HTML5.2) 作为W3C推荐标准发布 Javascript 的发展 1994年12月, Netscape 公司发布了Navigator1.0版,市场份额一举超过90% 1995年12月4日,Netscape公司与Sun公司联合发布了JavaScript语言 1996年3月,Navigator 2.0浏览器正式内置了JavaScript脚本语言 1996年11月,Netscape公司决定将JavaScript提交给国际标准化组织ECMA 1997年7月,ECMA组织发布ECMA-262的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript 2011年6月,ECMAscript 5.1版发布,并且成为ISO国际标准 2015年6月,ECMAScript 6正式发布,并且更名为 ECMAScript 2015 CSS 的发展 1996年 CSS level1发布 1998年 CSS level2发布 1999年 CSS level3提起草案 image.png //static.xiedaimala.com/xdml/image/f40ceb64-df08-4420-9226-7f76dbff15d5/2018-7-16-16-25-36.png 前端的发展 ~ 1998 原始社会 大多数网站都基于完整的HTML页面。 每个用户操作都要求从服务器加载完整的新页面。 用户体验反映出这个过程效率低下:所有页面内容都消失了,然后出现了新页面。 每次浏览器因部分更改而重新加载页面时,即使只有部分信息发生了变化,也必须重新发送所有内容。 这给服务器带来了额外的负担,并使带宽成为性能的限制因素。 1998~2004 奴隶制社会 各种浏览器纷争、各种不兼容。夹杂少量创新,如一些浏览器对异步加载数据各种不规范实现(Microsoft Outlook Web App)。 2004~2005 Ajax 问世 以 Gmail 和 Google Map 为标志的大量使用异步数据渲染的技术的产品问世。2005年Jesse James Garrett 在一篇文章中正式提到 Ajax 这个词。2006年 W3C 发布XMLHttpRequest的标准化草案。 封建社会 2006~2009(2012) 以 jQuery 的出现为标准,进入 jQuery 一统天下的时代。同时期出现Prototype、YUI、Dojo 、Extjs等占山为王,SPA 的产品越来越多出现在视野。 在这个阶段不得不提的工具是:网页开发三剑客 2009年 Node.js 诞生 创始人为Ryan Dahl,前端开始涉足后端。Node 生态衍生出各种框架和工具集。 2009(2012) ~ 2012 工业社会 UI 框架如 Bootstrap(2011) CommonJS 规范到 AMD 规范(Requere.js、Sea.js) SPA 的流行: Backbone.js 移动端的流行: Zepto.js 前端工程化工具的出现: Grunt(2012)、Gulp(2013) 2012~现在 2010年, Google 发布Angular.js 2012年, Webpack 发布 2013年,Facebook发布UI框架库React.js 2015年 Facebook发布了React Native项目,将React框架移植到了手机端,可以用来开发移动端 App 2014年 尤雨溪发布了Vue.js more... 参考 Brendan Eich 的博客 (https://brendaneich.com/) Wiki-JavaScript (https://en.wikipedia.org/wiki/JavaScript) Wiki-CSS (https://en.wikipedia.org/wiki/Cascading_Style_Sheets) Wiki-HTML (https://en.wikipedia.org/wiki/HTML) Wiki-Browser Wars (https://en.wikipedia.org/wiki/Browser_wars) 本文作者:若愚,转载请联系作者
 574 ·  08月28日 13:50
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)
 665 ·  07月31日 15:37
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
进入文集查看更多文章

我的足迹

Ta 的足迹

完成 {{activity.targetable && activity.targetable.name}} 所属课程: {{activity.course && activity.course.name}}
时间:
加载更多