总结篇(四) -- 进阶

概述

本篇主要讲述声明前置、引用类型、函数作用域链、闭包、HTTP、Web安全和性能优化

声明前置

在进入一个执行环境后,先把 varfunction 声明的变量前置,再去顺序执行代码,如果出现同名,则覆盖。如果一个变量已经有值(包括函数)再 var 无效

引用类型

引用类型存储的是变量的地址,赋值仅仅是地址的拷贝

1
2
3
4
5
6
var a = 1
function increase( num ){
return num += 1
}
increase( a )
console.log( a ) // 1

JavaScript 中引用类型即对象,对象存储方式是,栈内存中存储地址,堆内存中存储数据

1
2
3
4
5
6
var obj = { a: 1 }
function increase( obj ){
obj.a += 1
}
increase( obj )
console.log( obj.a ) // 2

函数作用域链

函数在执行过程中,先从自己内部找变量,之后去创建当前函数所在的作用域中寻找,依次向上

1
2
3
4
5
6
7
8
9
10
var a = 1
function fn1(){
function fn2(){
cnsole.log( a )
}
var a = 2
return fn2
}
var fn = fn1()
fn() // 2

1
2
3
4
5
6
7
8
9
10
var a = 1
function fn1(){
var a = 2
return fn2
}
function fn2(){
console.log( a )
}
var fn = fn1()
fn() // 1

闭包

一个函数引用了外部的变量,这个变量 + 函数 === 闭包,外部作用域中的变量不能被释放,可以通过函数来操作这个变量

1
2
3
4
5
6
7
8
function bindName( name ){
return function( action ){ // 此函数 + name(argument[0])就是闭包
console.log( ` ${ name } is ${ action }ing ` )
}
}
var doing = bindName( 'xxx' )
doing( 'work' ) // xxx is working
doing( 'play' ) // xxx is playing

HTTP

HTTP(Hypertext Transfer Protocol)超文本传输协议,它是一种应用层的协议,主要规定了电脑之间传输内容的协议

  • 应用层协议:HTTP、DNS、SSH
  • 传输层协议:TCP、UDP
  • 网络层协议:IP
  • URI ==> 统一资源标识符
  • URL ==> 统一资源定位符

    HTTP 报文(HTTP Message)

    请求报文(Request Message)
    请求报文
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 请求行
    method path HTTP/1.1
    // 请求头
    key: value
    Host: 域名
    connection: 决定当前的事务完成之后,是否会关闭网络连接,如果该值是 keep-alive ,网络连接就是持久的,不会关闭,使得对同一服务器的请求可以继续在该连接上完成
    Pragma: no-cache ==> 与 Cache-Control: no-cache 效果一致,强制要求缓存服务器在返回缓存的版本之前将请求提交到源头服务器进行验证
    Cache-Control: no-cache ==> 同上
    User-Agent: 用户代理软件的应用类型、操作系统、软件开发商以及版本号
    Accept: 告知客户端可以处理的内容类型
    Referer: 当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的
    Accept-Encoding: 将客户端能够理解的内容编码方式--通常是某种压缩算法--进行通知
    Accept-Language: 客户端声明它可以理解的自然语言,以及优先选择的语言
    If-None-Match: 条件式请求首部。对于 GET 和 HEAD 请求方法来说,当且仅当服务器上没有任何资源的 ETag 属性值与这个首部中列出的相匹配的时候,服务器端会才返回所请求的资源,响应码为 200
    Cookie:
响应报文(Response Message)

响应报文

1
2
3
4
5
6
7
8
9
10
// 响应行
HTTP/1.1 HTTP-Status-Code
// 响应头
Cache-Control: 被用于在 HTTP 请求和响应中通过指定指令来实现缓存机制
Content-Encoding: 对特定媒体类型的数据进行压缩
Content-Type: 实际返回的内容的内容类型
Expires: 指定一个日期 | 时间,在这个 日期 | 时间之后,HTTP 响应被认为是过时的
Server: 处理请求的源头服务器所用到的软件相关信息
Set-Cookie: 服务器端向客户端发送 Cookie
Strict-Transport-Security: 安全功能,告知浏览器只能通过 HTTPS 访问当前资源,禁止 HTTP 方式

使用 Cookie + Session 可以使得无状态的 HTTP 请求可以记录稳定的状态信息

  • Cookie 是存储在浏览器里的一小段数据
  • Session 是一种让服务器能够识别某个用户的机制,或者说特指服务器存储的 Session 数据
    很多网站的静态资源使用 CDN 地址而非使用当前网站域名
    使用 CDN 加速。从 Cookie 角度上说,发送请求时都会带上 Cookie,但是 Cookie 有跨域限制,即请求相同域名才会带上 Cookie,CDN 与当前域名不一致,故请求 CDN 资源时不会带上 Cookie,使得请求加快,从而达到加速的目的
Session
  • Session 在生产环境中保存在数据库中
  • Session 是基于 Cookie 实现的

Web 安全

  1. 传输数据安全
  2. 浏览器安全机制
  3. 常见攻击: XSS 攻击、CSRF 攻击、点击挟持

数据传输安全

只要使用 HTTP 协议,无论做任何安全措施都是徒劳的,只有 HTTPS 协议才能保证数据在传输过程中的安全

数据加密

  1. 对称加密:加密和解密都是用同一密钥
    • 特点: 速度快
    • 常见算法:AES
  2. 非对称加密:加密和解密使用不同的密钥,成为公钥和私钥。数据用公钥加密后必须用私钥解密,数据用私钥加密后必须用公钥解密。
    • 特点:速度慢,CPU 开销大
    • 常见算法:RSA
  3. Hash:把任意长度数据经过处理变成一个长度固定且唯一的字符串,无法反向解密成原始数据
    • 特点:验证数据完整性
    • 常见算法:MD5、SHA1、SHA256

攻击方式(传输过程中)

  • 拒绝服务:攻击者让目标机器停止提供服务
  • 信息泄露:攻击者获取用户信息
  • 中间人攻击:攻击者通过各种手段,在服务端发出的 HTTP | HTML 报文与显示屏呈现出的 Web 页面之间做一些手脚,篡改网页的部分或者全部内容,从而改变用户在浏览器视窗中看到的内容
  • 重放攻击: 攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性

HTTPS 实现安全数据传输

主要方案
  1. 服务器生成一对公钥和私钥,公钥给浏览器
  2. 浏览器做对称加密,产生密钥,使用公钥加密密钥,发送给服务器
  3. 服务器接收到公钥加密的密钥,服务器使用私钥解密,从而得到密钥
  4. 服务器和浏览器使用密钥进行交流
确保浏览器得到的是真正的公钥

根 CA + 上级 CA + CA 机构

根 CA 担保上级 CA,上级 CA 担保 CA 机构

当一个网站要使用 HTTPS 时先需在一些国际认证的 CA 机构填写网站信息申请证书,而这些 CA机构还有上层 CA,最终有一个根 CA

上述三者都做对称加密,分别得到

  • 公钥根CA + 私钥根CA
  • 公钥上级CA + 私钥上级CA
  • 公钥CA机构 + 私钥CA机构

私钥根CA 加密 公钥上级CA
私钥上级CA 加密 公钥CA机构
私钥CA机构 加密 公钥

浏览器都会内置根 CA 和一些顶级 CA 的证书

浏览器所要做的

  1. 根据 公钥根CA 解密 私钥根CA
  2. 根据解密出的 私钥根CA 解密 公钥上级CA
  3. 根据解密出的 公钥上级CA 解密 私钥上级CA
  4. 根据解密出的 私钥上级CA 解密 公钥CA机构
  5. 根据解密出的 公钥CA机构 解密 私钥CA机构
  6. 根据解密出的 私钥CA机构 解密 公钥

至此浏览器得到真正的 公钥
12306 网站
说明了 12306 网站的 HTTPS 证书没有机构为其担保,所以浏览器提示连接不安全

XSS 攻击

XSS 攻击是一种安全漏洞,攻击者利用这种漏洞在网上注入恶意的客户端代码,详细请看

避免方式
  1. 所有用户输入的地方都是不安全的,所以不要把用户提交的东西作为 HTML 去运行,即不使用 innerHTML
  2. JavaScript 中不要使用 eval()

CSRF(跨站请求伪造) 攻击

原理

攻击者构造网站后台某个功能接口的请求地址,诱导用户去点击或用特殊方法让该请求地址自动加载,用户在登录状态下这个请求被服务端接受后会被误以为是用户合法的操作,对于 GET 形式的接口地址可轻易被攻击,对于 POST 形式的接口地址也不是百分百安全,攻击者可诱导用户带 Form 表单可用 POST 方式提交参数的页面

避免方式
  1. 用户提交数据时 + 验证步骤
  2. 后端给前端传输的数据中,生成随机数,把随机数使用 Set-Cookie 写入到 Cookie 中,同时把随机数写到 Form 表单中(<input type='hidden' CSRF='随机数'),当用户提交表单时,服务器收到请求后查看 Form 表单中随机数是否 === Cookie 中随机数

性能优化

性能优化主要分为加载优化 + 体验优化两方面

加载优化
  1. 服务器网速要好,宽带够,使用 CDN
  2. 把所有资源压缩,尤其是图片压缩,选择合适的图片大小,HTML、CSS、JS 压缩
  3. 减少请求,生产环境资源打包合并
  4. 后端接口速度加快
  5. 利用缓存,能重复利用的都重复利用,Cache-Control + ETag
体验优化
  1. 只给用户暂时需要的东西,按需加载 + 懒加载
  2. 代码性能优化
  3. CSS3 动画优先,其次是 JS 动画,transform > position + left > margin-left