Browser
浏览器引擎
- 渲染引擎:获取解析网页内容,构建DOM、CSS等,计算网页layout,绘制网页
- JavaScript引擎:解释执行JavaScript
随着JavaScript的发展,分离出了JavaScript引擎。
浏览器内核
Trident
: IE系,包括360,搜狗Gecko
: Firefox系WebKit
: Safari系,以及魔改版Webkit的Chrome
HTML
HTML5新特性
- 语义化标签
- 音频视频API
- Canvas API
- localStorage 与 sessionStorage
- WebSocket
语义化
在HTML5中,所有标签具有其书面上的语义,即具有他要传递的内容是什么。语义与显示分离,显示全部由CSS3负责。
优点:
- 提升可访问性(对于使用ScreenReader)与互操作性
- 改进搜索引擎优化
- 一般使HTML文件更小
- 更好维护,表示层在CSS中
语义标签
<nav>
导航标签,里面通常是列表<ul>
或者<ol>
<article>
表示一个页面、文档、应用、容器,对<section>
的聚合<section>
表示文章中的一个段落、一个对话框的标签页等<aside>
侧栏标签,包括侧边栏、广告、友情链接等<label for="xx">
定义form关系,点击label会跳转到相关的input
上
Cookie与localStorage、sessionStorage区别 (多标签页之间通信)
cookie小于4kb,在每次http请求中携带,具有设定的有效期
localStorage和sessionStorage大于4MB,永久存储/关闭窗口后消失,保存在本地
离线存储网页
在没有因特网时通过缓存使用网页,在有网络连接时更新网页缓存
用法:
|
|
在cache.mainfest
文件内书写缓存规则:
- CACHE:表示需要离线存储的资源列表
- NETWORK:表示在它下面列出来的资源只有在在线的情况下才能访问,他们不会被离线存储
- FALLBACK: 如果第一个资源访问失败,就访问第二个资源替代
CSS
盒模型
content + padding + border + margin
box-sizing
属性: content-box
(默认值) or border-box
,前者width指定content的宽度,后者width指定了content+padding+border的宽度
块级元素与行内元素
display: block
块级元素具有自定义的width、height属性,并且左右换行
display: inline
行内元素不具有width等属性,由内容撑开,左右不换行
display: inline-block
左右不换行的行内显示,但是可以指定width和height等属性。
Float与清除浮动
浮动元素脱离文档流。浮动的框可以向左或向右移动,直到他的外边缘碰到包含框或另一个浮动框的边框为止。
可以实现文字环绕图片,但是浮动可能导致的问题。Image的父容器div依靠内部元素撑开,如果图片浮动,父div:
- 父元素height无法被撑开
- 背景不显示(因为没有height)
- margin值不正确显示
解决方法:
- 给父元素添加属性
overflow: auto
- 加入一个兄弟节点,具有属性
clear: both
- 将上面方法用CSS after实现
文档流(normal flow)与定位(Position)
文档流是相对于盒模型来讲的,指从左到右从上到下的正常布局
float: left
、position: fixed
、position: absolute
会导致DOM脱离文档流,位于上一层
static
:忽略top、left、z-index等声明,出现在正常文档流relative
:相对于其正常位置absolute
:相对于非static的最近祖先fixed
:相对于浏览器窗口
可以通过z-index
来改变文档堆叠顺序,其计算顺序为: 子元素的z-index
不能大于其父元素,越大越位于上方。
CSS选择器和权重
以 10 为基本单位
1000.内敛选择器 > 100.ID选择器 > 10.class选择器 > 1.元素选择器
同优先级最后一个覆盖前一个
垂直/水平居中的实现方法
方法一: 利用绝对定位
方法二: 利用table的效果(父级container高度自适应)
方法三: flex布局
通过align-self: center
属性实现交叉轴(竖直方向)的居中
单行文字垂直居中:
设置line-height
与height
相等
多行文字垂直居中:
- 设置
padding-top
等于padding-bottom
- 设置一个
span
包围多行文字,设置span
为diplay:block
,然后可以设置vertical-align
JavaScript
延迟加载JS的方法
- defer 和 async
- 动态创建DOM,创建script标签,设置src属性并插入DOM tree(JSONP的实现)
原生JS操作
|
|
Web优化策略
- 请求数量:合并脚本和样式表, iconfont,拆分初始化负载(一开始只加载必要脚本),划分主域(增加DNS查询代价,但是增加了并发链接数)
- 请求带宽:开启 GZip,精简 JavaScript,移除重复脚本,图像优化
- 利用缓存:使用 CDN,使用外部 JavaScript 和 CSS,减少 DNS 查找
- 页面结构:将样式表(影响样式的内容)放在顶部,将脚本放在底部,尽早刷新文档的输出
Web应用从服务器主动推送Data到客户端
- HTML5提供的WebSocket
- AJAX 长链接
- AJAX 长轮询
一个页面从输入URL到加载完成的过程
- 键盘按下发出中断,扫描其接口信息,经过操作系统传递给应用(浏览器);
- 浏览器开启一个线程来处理这个请求,对 URL 分析判断如果是 http 协议就按照 Web 方式来处理;
- 通过DNS解析获取网址的IP地址,设置 UA 等信息发出第二个GET请求;
- 进入HTTP会话;
- 服务器端Apache、Node.JS等响应请求,根据路由,经过相应应用(中间件)处理;
- 结束处理,如果修改时间和缓存一致返回304,否则返回200和该资源;
- HTML一边下载一边解析,根据标签建立文档树 DOM;
- 根据标记下载所需CSS、JS、图片文件,CSS阻塞式简历CSSOM,最终合并DOM和CSSOM,形成render tree,进行layout和painting;
- 当 JS 运行完成,页面加载完成。
new操作符做了什么
- 新建一个空白对象,并且继承该函数的原型,然后用this引用该对象
- 添加属性和方法
- 隐式返回this
JavaScript继承
|
|
闭包
闭包是一个嵌套在内层的函数和被他所捕获的外层变量
跨域及其解决方案 (腾讯)
详情参见同源政策与跨域详解
- CORS: 需要浏览器+服务器的支持。浏览器在Header中加入
Origin
字段,如果Origin在许可范围,服务器返回响应多出几个Access-Control
字段
// Todo:CORS详解,同服务器不同域名请求 (腾讯)
- JSONP: 123JSONP在URL中向服务器传递一个callback function,在JavaScript中定义了该function的行为。当服务器端接收到请求后,将数据用该function包括起来,类似于 jsonp(data) { ... }并返回该脚本文件。客户端接收到请求后,自动运行之前定义个callback function,即对跨域数据进行了操作
AJAX操作
- 创建XMLHttpRequest对象 (状态0)
- 设置HTTP请求状态变为4(完成)时的回调函数
- 通过OPEN创建请求,指定方法,URL等 (状态1)
- SEND发送请求 (状态2)
- 使用JavaScript实现DOM刷新 (状态3下载,4时调用回调函数)
利用setTimeout多次调用
在其回调函数再次调用自身即可
事件冒泡与事件捕获
- 事件冒泡:从子元素到父元素依次触发其上事件的回调函数
- 事件捕获:先触发父元素上的事件,再向下依次传递到子元素
在addEventListener
中,第三个参数设置为true启用事件捕获。当既存在事件冒泡,又存在事件捕获时,优先事件捕获
事件代理/事件委托 (jQuery 中 bind 和 on)的区别
事件委托将需要多个子元素触发的事件绑定到父元素上,通过 e.target 来判断是否是指定的子元素,进而触发回调
Attribute 和 Property 的区别
前者是DOM作为HTML标签的属性,后者是DOM作为JavaScript对象的属性。
- 共同点:许多attribute具有对应的property
- 不同点:用户自定义的attribute和自定义的property之间没有关系
Promise 规范
解决了之前异步操作的Callback Hell
,将横向的操作变为了纵向的操作。具有4种状态:pending、fulfilled、rejected、settled。
使用:将之前的异步回调包装进Promise,操作成功调用resolve
、失败调用reject
。然后在then中运行原本的回调任务。
改变运行上下文
方法:bind
、apply
、call
用处:绑定上下文(保持其始终获取某个上下文)、代理函数(自定义log代理console.lo)等
如何让接受多个参数的函数接受一个数组作为参数(例如 Math.max) (讯飞)
|
|
DOM操作性能
- 使用变量缓存DOM查询结果,减少查询操作
- 减少导致页面重绘(layout painting)的操作(改变widht、height。使用CSS动画)
- 使用更加精准的选择器(id选择器、类选择器)
前端渲染与后端渲染比较
前端渲染不利于SEO,服务器端为了前端渲染,需要花费更多时间将对象字符串化
后端渲染增大了网络传输体积与损耗,容易造成延时(白屏)
Virtual DOM
DOM元素非常庞大,具有复杂的属性,牵一发而动全身。通过JavaScript来模拟DOM树的结构,加快响应时间
- 建立虚拟DOM树:用JavaScript对象记录节点类型、属性、子节点。通过递归该虚拟DOM建立真正的DOM树
diff算法:因为跨层DOM操作很少,只比较同层DOM,从而将O(n^3)的比较降低到O(n)复杂度,深度优先遍历,记录差异:
- 替换节点类型: div -> p
- 增、删、调换子节点
- 修改节点属性
- 修改文本内容
记录差异类型,差异内容,压入patch数组
- 根据patch数组,对真实DOM进行操作。
Babel 运行时 (腾讯)
Babel可以编译几乎所有ES6语法(比如块级作用域,class语法糖),但是对于环境不支持的API没有办法,解决方案主要是:
- babel-polyfill: 在全局对象
global
上挂载对象API,比如Promise
等,缺点是会污染模块使用者 - babel-runtime: 手动在模块中require需要的API,比如
const Promise = require('babel-runtime/core-js/promise')
,缺点是打包可能存在多个引入语句,通过babel-plugin-transform-runtime
模块重新打包避免这个问题
JSON概念,作用,结构
JSON是一种数据格式,可以用来交换、存储数据。从JSON可以方便的生成JS对象。
其语法可以认为是JS Object的子集,主要区别在:
- JSON的键必须带引号,JS可以不带(解释器自动加)
- JSON没有函数、undefined、NaN等数据类型
网络
TCP 协议的三次握手
- Client -> Server : SYN = 1, SEQ = x
- Server -> Client : SYN = 1, ACK = x+1, SEQ = y
- Client -> Server : ACK = y+1, 可以携带payload
HTTP状态码
- 1**:暂时性回复。表示接收到请求并且继续处理
- 2**:响应成功。表示动作被成功接收、理解和接受
- 3**:重定向。
- 301:请求的网页已永久移动
- 302:临时重定向
- 304:自从上次请求,内容未更改过
- 4**:错误请求类
- 403:禁止访问
- 404:找不到如何与 URI 相匹配的资源
- 5**:服务器内部错误
WebSocket
在HTTP中,链接必须严格遵守1 request 1 response的规范,并具有HTTP header开销
WebSocket是一种兼容现有浏览器握手规范的新协议。用于实现低延迟的长链接,双方都可以随意发送数据。解决了以往需要用AJAX长轮询实现的推送,并且为浏览器FPS等低延迟需求带来可能。
缺点目前主要是浏览器兼容性,服务器维持长链接也需要一定成本。
安全
TLS(SSL) 原理详解 (腾讯)
HTTPS可能被监听/篡改吗?
// Todo….
SQL注入
通过把SQL命令插入到Web表单中递交,或插入到输入包含查询字符串(query string)的 url,最终达到欺骗服务器执行恶意的SQL命令
前端需要做到:
- 永远不信任用户输入,在后端对用户输入校验
- 加密密码等关键信息
CSRF
在危险网站B,向信任网站A发出请求(如转账),因为携带了A的Cookie,所以A认为是你自己发出的
前端需要做到:使用Cookie中不保存的,不可伪造的数据
- 添加验证码
- 添加token并且验证
XSS
攻击者向网站插入恶意HTML、JavaScript代码(比如留言板,论坛发帖),其他人看到时,将运行这段恶意代码
前端需要做到:
- 对用户输入的
<
、'
等特殊字符加以过滤 - 转义特殊字符到HTML