[关闭]
@FunC 2017-08-10T08:54:12.000000Z 字数 8334 阅读 2083

题目记录

前端


不用循环创建下标和索引相同的数组(注意本来数组的键就是数字,遍历键名)

  1. //ES5
  2. //apply的第二个参数是类数组,所以这里的{length: 100}会识别成一百项undefined的数组
  3. //Object.keys()返回对象属性字符串组成的数组,而数组的属性就是下标
  4. Object.keys(Array.apply(null, {length: 100}));
  5. //ES6
  6. //array.keys()是一个迭代器,value等于下标,用扩展运算符展开就是下标组成的数组了
  7. [...Array(100).keys()]

零碎

各种事件

触摸事件

  1. if(window.PointerEvent) //IE 11 & Edge
  2. {
  3. $('#holder').on('pointermove', printcoordinate);
  4. }
  5. else if(window.MSPointerEvent) //IE10
  6. {
  7. $('#holder').on('MSPointerMove', printcoordinate);
  8. }
  9. else //Chrome, Safari
  10. {
  11. $('#holder').on('touchmove', printcoordinate);
  12. }

300ms延迟的解决方案:

  1. <meta name="viewport" content="user-scalable=no">
  2. <meta name="viewport" content="initial-scale=1,maximum-scale=1">
  1. <meta name="viewport" content="width=device-width">

只绑定在touchstart上的坏处

  1. 滚动也会触发
  2. 点击穿透:因为click事件在300ms后触发,如果触发时原touchend的位置是一个链接,将跳进链接。

各种标签的特性、HTML5新标签

CSS动画

CSS权重

各种布局

  1. 文字环绕图片:同一div里面,img浮动,文字用div包围;使文字不环绕:margin-left、或者overflow:hidden制造BFC。注意文字div浮动会换行,虽然形成BFC,但是宽度不足以容纳这两个浮动元素...

圣杯布局

双飞翼布局

自适应正方形

  1. //最佳方案(缺点是兼容性差)
  2. .rect{
  3. width:100vmin;//vmin为1%视窗宽高中较小的一个
  4. heigth:100vmin;
  5. }
  6. //利用padding、margin的百分值计算依赖于父元素的width,无法实现横屏时的自适应
  7. .rect{
  8. width: 100%;
  9. background-color: lightblue;
  10. }
  11. .rect:after{
  12. display: block;
  13. content:' ';
  14. padding-top:100%;
  15. }

根据子元素数量的不同应用不同的css

  1. //一个元素既是第一个也是倒数第四个=>只有四个子元素
  2. //这时的相邻兄弟元素就是2,3,4
  3. //再加上自己=>仅有4个子元素时选择全部子元素
  4. .li:first-child:nth-last-child(4),
  5. .li:first-child:nth-last-child(4) ~ li {
  6. // 假设需求是近当有4个li时为四宫格
  7. padding-top: 50%;
  8. width: 50%;
  9. }

关于inline-block之间的空白

  1. //a标签之间会有无法点击的空白,这是由于换行符导致的(不换行或不闭合
  2. //可在nav设置font-size:0;或者改用flex
  3. <nav>
  4. <a href="#">One</a>
  5. <a href="#">Two</a>
  6. <a href="#">Three</a>
  7. </nav>

图片底部的空白

基于baseline,可让父元素font-size:0;或极小的line-height;或使用flex

闭包...写在jQuery里

闭包(for循环setTimeout,onclick一类)

为什么用let就能解决?
原本用var,循环体属于全局作用域,i也在全局作用域内。
当计时器到达后,开始寻找变量
使用var时,顺序是:事件绑定函数作用域→上一级作用域→...→全局作用域
当使用let时,使循环体形成了块级作用域,即每一个循环体都是不同的作用域
顺序是:事件绑定函数作用域→循环体作用域→上一级作用域→...→全局作用域
相当于

  1. {
  2. let i = 1;
  3. setTimeout(() => console.log(i)}, i*1000);
  4. }
  5. {
  6. let i = 2;
  7. setTimeout(() => console.log(i)}, i*1000);
  8. }
  9. {
  10. let i = 3;
  11. setTimeout(() => console.log(i)}, i*1000);
  12. }

从垃圾清理角度讲,当当前作用域结束后,会尝试清理不再被引用的变量。
使用var时,循环体为全局作用域,全局作用域在关闭环境时才清除。
而使用let时,循环体为块级作用域,每次循环都要尝试清除不再被引用的变量,而这时i被setTimeout的console.log引用着,所以形成了闭包(?)
传统的使用闭包(立即执行函数传参数)的解决方案其实就是在模拟块级作用域。

update: ES6中的let在循环中的行为进行了特别规定
所以其实内部完成了赋值:

  1. for (let i = 0; i < 10; i++) {
  2. let j = i; // 实际上内部多了这一步
  3. console.log(j);
  4. }

缓存如何处理

nodejs的流

基于buffer实现,继承自EventEmitter
自动控制后端压力,可以链式调用,方便
fs.readFile('./sthBig.gz', callback)需要将整个文件读入内存,才能返回结果(大量请求时消耗巨大)
改成fs.createReadStream('./sthBig.gz'),每次读一个chunk,中间还能处理(如使用split()模块调整为每chunk一行)需要加工时可使用transfromliu(如through2模块),读写完后的回调可以通过监听'close'事件来触发。
readstream,只可读(但在消耗前可通过readstream.push(sth)写入缓存)
writestream,只可写,还能通过.write()/.end()(不再可以写入)来写入
transfrom,可读可写,但不存数据。中转,中间处理(如a.pipe(b).pipe(c))中的b
duplex,可读可写存数据,如a.pipe(b).pipe(a)中的a。

docment文档流

HTML文档能流式处理 -> 所以其实document也有.open(), .write(), .close()方法
在文档解析中途进行.write():附加在文档尾部
文档加载结束后, 调用了.close()关闭文档流
此后再次调用.write(), 则强行先执行一次.open(),即开启新的文档流-> 故此后再write()会覆盖页面内容

webpack工作原理

gulp工作原理

客户端检测

跨域

  1. 图片ping,图片有onload和onerror事件,但无返回内容
  2. JSONP 利用script标签src可跨域的性质,动态构建script标签,URL可用?callback=xxx指定回调函数。服务器返回callback({json});
  3. 直接AJAX尝试跨域:使用绝对地址,发送时会带上Origin头。需要服务端响应中Access-Control-Allow-Origin头部支持相同的源,或者“*”(公共资源)。默认跨域请求不带凭据(cookie,http认证(即用户&口令)及客户端SSL证明等),如果想带凭据,请求头要设置withCredentials:true,且服务端Access-Control-Allow-Credentials:true支持。
    另外,如果跨域请求方法为GET、POST、HEAD以外的方法,使用了某些头部、以及POST搭配application/x-www-form-urlencoded
    multipart/form-data
    text/plain以外的主体内容时,会使用OPTIONS发送Preflight请求
    Preflight请求头包括:Origin Access-Control-Request-Method Access-Control-Request-Headers(可选,自定义头部)。响应头对应Access-Control-Allow-Origin Access-Control-Allow-Method Access-Control-Allow-Headers Access-Control-Max-Age

css

浮动

float失效:
1.position:absolute/fixed;
2.display:flex

不定宽高水平垂直居中

    1.
  1. .parent{
  2. display:flex;
  3. justify-contet: center;
  4. align-items: center;
  5. }
    2.
  1. .parent{
  2. position: relative;
  3. }
  4. .child{
  5. position: absolute;
  6. top: 50%;
  7. left: 50%;
  8. transform: translate(-50%,-50%)//自身的50%
  9. }
    3.
  1. .parent{
  2. display: table-cell;
  3. text-align:center;
  4. vertical-align:middle;
  5. }
  6. .child{
  7. display: inline-block;
  8. vertical-align: center;
  9. }

ES6新特性

git 远程仓库

  1. git remote add origin xxxxxxxx
  2. //首次要用-u push上去同时关联文件
  3. git push -u origin master
  4. git push origin master
  5. //克隆远程库
  6. git clone xxxxxx

http各种请求、状态、第一次请求与再次请求

排序算法

CDN加速

web性能优化

  1. 请求数量:雪碧图,js文件合并,拆分初始化荷载
  2. 请求带宽:压缩文件gzip,压缩css和js,拆分初始化荷载
  3. 缓存利用:设置expires、cache-control头,使用CDN加速,减少DNS查询
  4. 页面结构:link放head,script放body结束前
  5. 代码校验:避免CSS表达式,避免重定向

从输入url到展示页面发生了什么

  1. 检查缓存(有无过期,是否需要服务端验证)
  2. 查找域名IP地址(有无缓存,浏览器,host,本地DNS服务商,最后DNS迭代查询)
  3. 建立TCP连接(三次握手四次挥手的状态名?原因)
  4. 发送HTTP请求(请求头的内容)
  5. 接受HTTP请求(响应头的内容)
  6. 解析html,css,js

switch的比较操作

  1. 'A' !== new String('A'); //true
  2. new String('A') !== new String('A'); //true

关于数组

简单总结就是:
1. 非数字下标会忽略
2. length可写

  1. var arr = [];
  2. arr['a'] = 'a';
  3. console.log(arr.length);//0
  4. arr['2'] = 2;
  5. console.log(arr.length);//3
  6. arr.length = 0;
  7. console.log(arr.length);//0
  8. arr.length = 3;
  9. console.log(arr);//[undefined,undefined,undefined]

关于JS中浮点数的计算

思路:将浮点数转换为整数,计算后再切换为小数。
1. 用 split('.');判断小数点位数n
2. 取位数最大的,分别乘10的n次方
3. 重点:对结果使用parseInt(),转换为真正的整数
4. 整数运算,再除以10的n次方

获取元素宽高、位置

  1. //宽高
  2. element.offsetHeight
  3. element.offsetWidth
  4. //绝对位置
  5. element.offsetTop
  6. element.offsetLeft
  7. //相对位置
  8. var rectObj = element.getBoundingClientRect();
  9. //只读
  10. rectObj.left
  11. rectObj.top
  12. rectObj.right
  13. rectObj.bottom
  14. rectObj.height//IE8及以下没有宽高
  15. rectObj.width

CSRF跨站点请求伪造

伪造用户的请求,如让用户访问钓鱼网站,网站向目标站点发起请求,此时会带上用户的cookie使验证通过
cookie分为:session cookie(临时cookie)、本地cookie(expire之后才失效)(部分标签的请求禁止携带本地cookie,如img、iframe、script、link)

CSRF的防御:
1. 验证码(需要用户互动才能完成操作,但仍有可能被钓鱼。且不可能全部请求都加验证码)
2. referer过滤:过滤不合理的referer(但服务端不一定能取到referer,有时出于隐私考虑会闲置referer的发送)
3. 依赖AJAX的CORS配合JSON API:因为AJAX限制跨域,而能跨域的form标签不能发送JSON
4.CSRF token:(从本质出发)

CSRF本质:重要操作的所有参数能被猜到(才能构建出请求)
请求中带上随机数token
token由服务端发给客户端,请求时需要带上token进行验证

token注意事项:

  1. 放在表单的隐藏项中,敏感操作改为post
  2. 避免token出现在**页面的**URL中,此时可能通过referer被记录
  3. token不能被ajax获取到(不要提供/csrf路由)
  4. token只能避免CSRF,如果攻击者能使用JavaScript(如XSS攻击),token自然无效

XSS攻击(实质为HTML注入,用户输入数据被作为HTML执行)

  1. 反射型XSS:
    将用户输入数据“反射”在浏览器上,攻击者需要诱导用户点击恶意链接才能成功
  2. 存储型XSS:
    恶意代码储存在了服务端。例如:发表了一篇含恶意代码的文章,文章储存在服务端,所有访问这篇文章的用户都会被影响。

可能输出位置
1. HTML标签中<div>$var</div> 构造script标签或使用事件属性等
2. HTML属性中,使用引号闭合属性
3. CSS中输出:含url()的属性,配合JavaScript、dataURI等伪协议等
4. 对于富文本:使用白名单

XSS防御:

  1. 对于cookie劫持:使用HttpOnly
  2. 输入检查(客户端服务端都要检查,减轻服务端压力):XSS Filter(但是只检查了输入的数据,没有检查渲染后的HTML页面代码)
  3. 输出检查:HtmlEncode

cookie与session

(set-cookie: key=value; expirse: GMT time; max-age:xxxs; domain: path: secure;等)
cookie储存于客户端,session储存于服务端。
cookie是客户端的状态保持方案(HTTP协议无状态)
session是客户端与服务端状态保持的解决方案(如购物车的添加),需要依赖客户端保存相应的标识(如sid),所以依赖于cookie(较好的实现方案)。
session可避免cookie直接存储敏感信息。

以用户登录为例:
1. 用户提交用户名密码的表单(经过前端加密(配合验证码哈希)/HTTPS)
2. 服务端验证用户名密码
3. 如果验证通过, 生成一个会话对象(检查有没有同用户的会话,有就删除,实现单用户登录),里面含有sid,用户名,以及其他敏感信息,如logIn=true,设置set-cookie:sid=value
4. 下次发起请求时cookie带有sid,服务端通过sid寻找对应的会话并根据状态进行操作。
5. 一个会话不会因为客户端关闭而结束,故一般有过期时间(进行‘登出’操作能主动关闭session)

cookie的安全

  1. 设置HttpOnly。能用JavaScript操作的同样能通过在服务端设置响应头完成。
  2. 域的设置:最小化授权,让cookie能被访问的范围下降到最小。
  3. 设置secure,只能通过https发送这种cookie

vue原理

  1. Object.defineProperty() 的set 触发notify(),通知订阅者数据发生变更。
  2. Mutation Observer监视DOM变动,类似于事件,不过是异步触发(如添加1000个节点,全部添加完后才触发一次)。MutationObserver在tick的最后触发(同promise)。如不支持,退化为setTimeout(fn, 0),在下一个tick一开始进行。
  3. 本质:
  1. onStateChange(() => {
  2. view = render(state)
  3. })

即state何时change?(修改setter,进行notify)
render哪些部分?组件内VNode diff
Watcher(监听表达式、回调操作)、Dep(watcher依赖收集)、Observer(其实只是响应化)的相互依赖
具体见

箭头函数中的this

指向定义时的父级的this,自身无this
因为自身无this,所以也不能通过.bind().call().apply()方法改变this。
如果作为函数被return出来,因为自身无this,所以其实形成了一个闭包,指向上一级的this。

  1. //用例数据
  2. var obj = {
  3. name: 'mike',
  4. sayHi: function(){
  5. console.log(this.name);
  6. },
  7. say: () => {
  8. console.log(this.name);
  9. }
  10. }
  11. var name = 'ben';
  12. //函数部分
  13. function c(){
  14. return () => console.log(this.name)
  15. }
  16. c()();//ben 指向父级的this,父级的this为window
  17. c.bind(obj)()();//mike 指向父级的this,父级的this绑定为obj
  18. c().bind(obj)();//ben bind无效

运算符优先级

圆括号 > 成员访问(.[]) = 带参数的new() > 函数调用(fn()) = 无参数的new > 后置递增/递减(...++ ...--) > 除扩展运算符外的一元运算符

关于同源、cookie和localstorage

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注