1. 计算机网络分层:分层每层有每层的作用,带来分工合作,方便问题排查

image.png

  1. OSI七层网络模型

image.png
image.png

跨域

  1. 同域:协议、域名、端口三个都相同称为同域,反之被称为跨域
  2. 实现跨域通信的九种方法

    1. jsonp

      1. 缺点:只能发get请求,不支持其它的请求方法
      2. 缺点:不安全,请求别人的网站,如果jsonp返回一个脚本标签就等于返回到自己的页面中来执行,有可能产生XSS ``javascript function jsonp({ url, params, cb }) { return new Promise((resolve, reject) => { let script = document.createElement('script') window[cb] = function(data) { resolve(data) document.body.removeChild(script) } params = {...params, cb} let arrs = [] for (const key in params) { arrs.push(${key}=${params[key]}) } script.src =${url}?${arrs.join(‘&’)}` document.body.appendChild(script) }) }

      jsonp({ url: ‘http://www.baidu.com‘, params:{ wd: ‘jack’ }, cb: ‘getData’ }).then(data => {}) ```

    2. cors ```javascript // 跨域的请求已经发送到服务端了,服务端也有返回,只是被浏览器进行了拦截

  3. 服务端设置响应头,指定可跨域的源 let whiteList = [‘http://localhost:3000‘] let origin = res.headers.origin if (whiteList.includes(origin)) { res.setHeader(‘Access-Control-Allow-Origin’, origin) }
  4. 如果客户端设置了自定义的请求头,则服务端需要设置允许的响应头,否则也会跨域 client.setHeader(‘name’, ‘jack’) res.setHeader(‘Access-Control-Allow-Headers’, ‘name’)
  5. 如果客户端请求的方法是PUT或其它方法,除了GET/POST默认支持,其它也需要设置允许的响应头 xhr.open(‘PUT’, ‘http://localhost:3000‘) res.setHeader(‘Access-Control-Allow-Methods’, ‘PUT’) // 复杂请求会多发一次options预检请求,有两个作用,第一个:查询服务器支持的HTTP方法,第二个在跨域时查询是否支持跨域,后台可以设置预检请求的时间: res.setHeader(‘Access-Control-Max-Age, 6000’)
  6. cookie不允许跨域,服务器收不到,需要通过客户端与服务端共同设置才行 客户端设置:xhr.withCredentials = true 服务端设置:res.setHeader(‘Access-Control-Allow-Credentials’, true)
  7. 服务端设置自定义头给客户端,客户端也会报错,不支持获取不安全的头 res.setHeader(‘name’, ‘jack’) res.setHeader(‘Access-Control-Expose-Headers’, ‘name’) // 设置客户端允许获取哪个自定义头 ```

    1. postMessage ```javascript // 父向子iframe通信,获取iframe let frame = document.getElementById(‘iframe’) frame.contentWindow.postMessage(‘我来自父亲窗口’, ‘http://localhost:4000‘)

// 父子接收信息:都通过监听message事件 window.onmessage = function(e) { console.log(e.data) // 子向父发状信息 e.source.postMessage(‘来自子窗口’, e.origin) } // 子向父发状信息 window.parant.postMessage(‘来自子窗口’)

  1. 1. document.domain
  2. ```javascript
  3. 不同的一级域名,相同的二级域名之间通信 -- a.second.cn b.second.cn
  4. domain也用的比较多
  5. a.html
  6. documet.domain = 'second.cn'
  7. <iframe src="http://b.second.cn" onload="load()">
  8. function load(){
  9. // 获取b.second.cn中的数据
  10. frame.contentWindow.a
  11. }
  12. b.html
  13. documet.domain = 'second.cn'
  14. var a = 100
  1. window.name
  2. location.hash
  3. http-proxy
  4. nginx
  5. websocket

HTTP1.1比HTTP1.0有哪些改变

  1. 增加了keep-alive长连接,减少了时延
  2. 增加了options、put等请求方法
  3. 增加了host请求头
  4. 增加了etag、is-match等缓存控制头
  5. 增加了range请求头域,可以请求资源的某一部分

正向代理与反向代理

  1. 正向代理
    1. 隐藏了真实客户端的真实身份
    2. 我向王老师借钱,王老师没钱,找马云借钱再借给我,马云不知道这钱到底在谁那里
    3. 正向代理的是客户端
  2. 反向代理:主要用来内容分发,缓解服务器压力,如Nginx
    1. b隐藏了真实服务端的真实身份
    2. 我向10086咨询问题,不知道对方是谁,只关注结果能否得到反馈
    3. 反向代理的是服务端

安全-XSS

  1. 反映型XSS,用户输入什么,页面就返回什么,不经过处理,输入的有可能是脚本
    1. 问题主要在于服务端未进行字符串编码 ```javascript
  2. 通过获取url的参数,未经处理直接返回给前端页面 http://localhost:3000/index.html?type=
  3. 获取到用户的cookie http://localhost:3000/index.html?type=
  4. encodeURIComponent编码字符串中的特殊字符,decodeURIComponent解码已经编码过的特殊字符 encodeURIComponent(‘http://www.cc/my test.asp?name=ståle&car=‘) ```

  5. DOM-Based型

    1. 问题主要在前端,改变原有DOM结构,会造成攻击
      1. $(box).innerHTML(`<img src=${encodeURI(${input}.val())}>`)
      2. <img src=""><srcipt>alert(1)</script>
      3. <img src="xxx" onerror="alert(1)">
  6. 存储型

    1. 比如将评论的内容未经转换发送到服务器,服务器存储起来,后来所有用户都可以访问到这个评论,造成所有用户的攻击
  7. 解决方案
    1. 客户端传递给服务器时,先检验过滤一下
    2. 服务端再做一次过滤
    3. 直接在输出的时候过滤
      1. function encodeHTML(str){
      2. return str.replace(/&/g, '&amp;').replace(/>/g, '&gt;')
      3. .replace(/</g, '&lt;').replace(/"/g', '&quot;')
      4. .replace(/'/g, '&apos;')
      5. }

      安全-CSRF

前端通信

  1. 单功:单向通信
    1. 喇叭向人广播
  2. 半双功:单双向通信
    1. 先请求,再响应
    2. 案例:客户端-服务端