导航

[[深刻01] 执行上下文](https://juejin.im/post/684490...
[[深刻02] 原型链](https://juejin.im/post/684490...
[[深刻03] 继承](https://juejin.im/post/684490...
[[深刻04] 事件循环](https://juejin.im/post/684490...
[[深刻05] 柯里化 偏函数 函数记忆](https://juejin.im/post/684490...
[[深刻06] 隐式转换 和 运算符](https://juejin.im/post/684490...
[[深刻07] 浏览器缓存机制(http缓存机制)](https://juejin.im/post/684490...
[[深刻08] 前端平安](https://juejin.im/post/684490...
[[深刻09] 深浅拷贝](https://juejin.im/post/684490...
[[深刻10] Debounce Throttle](https://juejin.im/post/684490...
[[深刻11] 前端路由](https://juejin.im/post/684490...
[[深刻12] 前端模块化](https://juejin.im/post/684490...
[[深刻13] 观察者模式 公布订阅模式 双向数据绑定](https://juejin.im/post/684490...
[[深刻14] canvas](https://juejin.im/post/684490...
[[深刻15] webSocket](https://juejin.im/post/684490...
[[深刻16] webpack](https://juejin.im/post/684490...
[[深刻17] http 和 https](https://juejin.im/post/684490...
[[深刻18] CSS-interview](https://juejin.im/post/684490...
[[深刻19] 手写Promise](https://juejin.im/post/684490...
[[深刻20] 手写函数](https://juejin.im/post/684490...

[[react] Hooks](https://juejin.im/post/684490...

[[部署01] Nginx](https://juejin.im/post/684490...
[[部署02] Docker 部署vue我的项目](https://juejin.im/post/684490...
[[部署03] gitlab-CI](https://juejin.im/post/684490...

[[源码-webpack01-前置常识] AST形象语法树](https://juejin.im/post/684490...
[[源码-webpack02-前置常识] Tapable](https://juejin.im/post/684490...
[[源码-webpack03] 手写webpack - compiler简略编译流程](https://juejin.im/post/684490...
[[源码] Redux React-Redux01](https://juejin.im/post/684490...
[[源码] axios ](https://juejin.im/post/684490...
[[源码] vuex ](https://juejin.im/post/684490...
[[源码-vue01] data响应式 和 初始化渲染 ](https://juejin.im/post/684490...
[[源码-vue02] computed 响应式 - 初始化,拜访,更新过程 ](https://juejin.im/post/684490...

前置常识

一些单词

specify:指定stable:稳固的amount:共计optional:可选的 optional object:可选对象ordinary:一般的omitted:省略的broadcast:播送outdated:过期的

NRM - nrm

  • nrm 的作用是 ( <font color=red>切换npm源</font> ) (npm的注册表管理器,能够切换npm的镜像地址)
  • npm, cnpm, taobao, nj(nodejitsu)等
  • command:命令
  • 全局装置后,报错解决

    • nrm : 无奈加载文件 D:\Program Files\nodejs\nrm.ps1,因为在此零碎上禁止运行脚本。
    • 解决办法:

      • (1) 用管理员身份关上cmd,输出以下命令
      • (2) set-ExecutionPolicy RemoteSigned命令将计算机上的执行策略更改为 RemoteSigned,输出Y确定
    • ExecutionPolicy:执行策略
    • 执行策略能够帮忙你执行不信赖的脚本
    (1) installnpm install -g nrm(2) useagenrm [options] [command] options-h,--help //----------------------------------- help-V,--version //-------------------------------- version numbercommondsnrm ls //------------------------------------------- 列出所有源nrm use <registry> //------------------------------- 应用具体哪个源nrm add <registry> <url> [home] //------------------ 增加源,(1) registry是源的名字,能够轻易取 (2) url源地址nrm del <registry> //------------------------------- 删除源nrm test [registry] // ----------------------------- 测速,返回响应的工夫

NVM - nvm

  • <font color=red>nvm 用于切换 node 和 npm 版本</font>
  • windows零碎上能够用 <font color=red>nvm-windows</font>
  • [教程:]()
  • 注意事项 !!!!!!!

    • 如果之前装置过node即零碎中存在node,须要将node卸载洁净,步骤如下

useagenvm use <version> [arch] //------------------ 应用哪个版本的node,(arch示意32位或64位,非必须)mvm list [available] // --------------------- 展现可用的node版本列表,(available示意无效,非必须)nvm install <version> [arch] // ------------- 装置指定的node版本,version示意具体的版本号nvm uninstall <version>
----查看全局装置的包:----------------- npm ls -g --depth=0查看全局装置的包:----------------- npm list -g --depth=0 // ls 和 list 都能够卸载本地全局安装包:--------------- npm uninstall -g xxxx查看须要更新的全局包:------------- npm outdated -g --depth=0 // outdated是过期的意思npm info xxxx // ------------------------------ 近程包的信息npm info xxxx version // ---------------------- 近程最新的版本号npm info xxxx versions // --------------------- 近程所有版本号

window.postMessage 跨域通信

  • window.postMessage 能够实现跨域信息交互,<font color=red>两个web浏览器标签页之间的通信</font>,<font color=red>IFrame</font> 通信等
  • otherWindow.postMessage(message, targetOrigin, [transfer]);
  • 留神:在targetWindow.open()后,要等到指标页面加载实现能力进行 postMessage 跨域通信,然而在跨域的状况下,无奈对指标窗口进行onload监听,所以能够用 setTimeout延时,对于IFrame同理
(一)otherWindow.postMessage(message, targetOrigin, [transfer]) 跨域通信(1) otherWindow- otherWindow指的是其余窗口的一个援用1. iframe 的 contentWindow 属性2. window.open() 返回的一个窗口对象3. 命名过或数值索引的 window.frames4. 两个窗口之间  - a -> b,otherWindow是b窗口  - b -> a,otherWindow是a窗口,即 ( top ) 或者 ( parent )(2) message- message指发送给其余窗口的数据- message会被序列化,所以无需本人序列化(3) targetOrigin     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!- targetOrigin:设置指标窗口的源(协定域名端口组成的字符串),指定哪些窗口能 ( 接管 ) 到音讯事件- 在 ( 发消息 ) 的时候,如果( 指标窗口 ) 的 ( 协定,域名,端口) 任意一项不满足 targetOrigin 提供的值,音讯就不会发送- 三者要全副匹配才会发送- targetOrigin的值能够是 (  *  ) 号,示意所有窗口都能接管到音讯(4) transfer- transfer 是一串和message同时传递的 Transferable 对象- 这些对象的所有权将被转移给音讯的接管方,而发送一方将不再保有所有权发消息:--------------- otherWindow.postMessage(message, targetOrigin, [transfer])收音讯:--------------- window.addEventListener('message', (data) => {console.log(data.data, data.origin)}, false)留神:----------------- 通过 ( targetOrigin - 验证接管方 ) 和 ( data.origin - 验证发送方 ) 来准确通信- data.origin 和 data.source 和 data.data- 在接收端的监听函数中,留神 origin 和 source- origin: ------------- 发送方的协定,域名,端口组成的字符串- source:------------- 发送方窗口对象的援用- data:--------------- 接管到的数据window.addEventListener("message", receiveMessage, false); // 接管音讯的tab标签页面监听message事件function receiveMessage(event) {  // For Chrome, the origin property is in the event.originalEvent  // object.   // 这里不精确,chrome没有这个属性  // var origin = event.origin || event.originalEvent.origin;   var origin = event.origin  if (origin !== "http://example.org:8080")    return;    // ...}(二)注意事项:- 应用postMessage将数据发送到其余窗口时,始终要指定准确的指标origin,而不是应用 *- 应用 origin 和 source 验证 ( 发件人 ) 的身份(三)实例:--------------a页面<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>Document</title></head><body>  <div id="a-open">点击,关上b页面</div>  <div id="a-send">点击,发送音讯,a->b</div>  <script>    const aOpen = document.getElementById('a-open')    const aSend = document.getElementById('a-send')    var a = null    aOpen.addEventListener('click', () => a = window.open('http://127.0.0.1:5500/b.html'), false)    aSend.addEventListener('click', () => a.postMessage('this message is a to b', 'http://127.0.0.1:5500'), false)    // 留神:    // 1. a.postMessage只有在指标页面(b页面)的页面加载实现时能力发送    // 2. a.postMessage的第二个参数,示意targetOrigin指标源,即指标窗口的协定域名端口组成的字符串    // 3. targetOrigin设置过后,只有指标窗口完全符合targetOrigin字符串的值能力接管到音讯  </script></body></html>---------------b页面<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>Document</title></head><body>  <div>b页面</div>  <script>    window.addEventListener('message', (data) => { // ----- 监听message事件      console.log(data)    }, false)  </script></body></html>

websocket概述

  • <font color=red>websocket是应用层协定的一种,建设在http协定之上,是一种双向通信的协定</font>
  • HTTP在1.1版本中也能建设长连贯 Connection:Keep-alive

    • 然而 ( HTTP ) 建设的长连贯实质上还是 request response 这样的模式,即 ( 一个request对应一个response )
    • 而 ( websocket ) 是 ( 全双工通信 )
  • TCP是传输层协定
  • HTTP 和 websocket 是应用层的协定
  • IP是网络层协定

WebSocket 客户端api

new WebSocket(url)

  • const ws = new WebSocket('ws://localhost:8080')
  • WebSocket 作为构造函数,用于新建 websocket 实例
  • ws:示意websocket协定
  • wss:示意websocket加密协议

webSocket.readyState

  • readyState 属性返回实例对象的以后状态,一共4种

    CONNECTING:0 --------------- 示意正在连接OPEN: 1 --------------------- 示意连贯胜利,能够通信了CLOSING:2 ------------------ 示意连贯正在敞开CLOSED:3 ------------------- 示意连贯曾经敞开,或者连贯关上失败

webSocket.onopen

  • 指定连贯胜利后的回调函数
  • 指定一个回调函数:ws.onopen = function(){}
  • 指定多个回调函数:ws.addEventListener('open', function(){})

webSocket.onclose

  • 指定连贯敞开后的回调函数

<font color=red>webSocket.onmessage</font>

  • <font color=red>指定收到服务器数据后的回调函数</font>
  • 留神:服务器返回的数据有两种可能 ( <font color=red>文本</font> ) 或 ( <font color=red>二进制数据 - blob对象或Arraybuffer对象</font> )
  • 判断数据数据类型:<font color=red> binaryType </font>

    • ws.binaryType = 'blob'
    • ws.binaryType = 'arraybuffer'
    • binary:二进制的
    ws.onmessage = function(event) {var data = event.data;// 解决数据};ws.addEventListener("message", function(event) {var data = event.data;// 解决数据});----------ws.onmessage = function(event){if(typeof event.data === String) {  console.log("Received data string");}if(event.data instanceof ArrayBuffer){  var buffer = event.data;  console.log("Received arraybuffer");}}

<font color=red>webSocket.send()</font>

  • <font color=red>wx.send() 用于向服务器发送数据</font>

webSocket.bufferedAmount

  • wx.bufferedAmount 示意还有多少字节的二进制数据没有发送进来,能够用来判断是否发送完结
  • wx.bufferedAmount === 0 示意发送完结
  • amount:共计的意思

webSocket.onerror

  • wx.onerror 指定报错时的回调函数

应用 websocket 和 nodejs-websocket 简略聊天室

客户端:<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>Document</title></head><body>  <input type="text" id="name-input">  <button id="name-button">创立名字</button>  <input type="text" id="input">  <button id="button">发送音讯</button>  <script>    const inputDom = document.getElementById('input')    const button = document.getElementById('button')    const nameInput = document.getElementById('name-input')    const nameButton = document.getElementById('name-button')    const ws = new WebSocket('ws://localhost:5555')     // ----------------------------------------------------- 生成websocket实例对象    // ----------------------------------------------------- 参数是url    // ----------------------------------------------------- 留神:协定是 (ws:// ) 或者 (wss:// 加密协议)    ws.onopen = function() { // ---------------------------- onopen:连贯胜利后的回调      // ws.send('客服端 => 发送给服务端的音讯字符串') // -- send():向服务端发送音讯      nameButton.addEventListener('click', () => {        nameButton.setAttribute('disabled', 'disabled')        ws.send(JSON.stringify({          type: 'name',          value: nameInput.value        }))      }, false)      button.addEventListener('click', () => {        ws.send(JSON.stringify({          type: 'chat',          value: inputDom.value,        }))      }, false)    }    ws.onmessage = function(e) { // --------------------------- onmessage:收到服务端返回数据时触发的回调      const p = document.createElement('p')      p.innerHTML = e.data      document.body.appendChild(p)    }/*    ws.addEventListener('open', connectedCallback, false)    function connectedCallback() {      ws.send('客服端 => 发送给服务端的音讯字符串')    }    ws.onopen = function() {      ws.send('客服端 => 发送给服务端的音讯字符串')    }    ws.onmessage = function(e) {      console.log(e.data)    }*/  </script></body></html>
服务端:const ws = require('nodejs-websocket')const server = ws.createServer(function(conn) {  console.log("New connection")  conn.on("text", function (str) { // ------------------------ 客户端发来的数据是text类型时触发       console.log("Received "+str)    // conn.sendText(str)    const data = JSON.parse(str)    switch(data.type) {      case 'name':          conn.nickname = data.value;          broadcast(data.value + '退出了房间');          break;      case 'chat':          console.log(data.value, 'data.value');          broadcast(data.value);          break;      default:        break;    }  })  function broadcast(str) { // --------------------------------------- broadcast:播送    server.connections.forEach((conn) => {      conn.sendText(str)    })  }    conn.on("close", function (code, reason) { // --------------------- 敞开连贯时触发    console.log("Connection closed")    broadcast(conn.nickname + '来到了房间')  })  // conn.send('服务端 => 发给客服端的音讯')  conn.on('error', (err) => { // -------------------------------------- 处理错误    console.log(err)  })})server.listen(5555, () => console.log('server runing')) // ------------- 监听端口

材料

https://juejin.im/post/684490...
阮一峰 http://www.ruanyifeng.com/blo...
nvm 和 nrm https://juejin.im/post/684490...
nrm官网:https://github.com/Pana/nrm
nrn装置后输出命令报错:https://blog.csdn.net/ougexin...
nodejs-websocket:https://github.com/sitegui/no...
otherWindow.postMessage:https://juejin.im/entry/68449...