一、WebSocket 协议
WebSocket 是个好东西,为我们提供了便捷且实时的通讯能力。然而,对于 WebSocket 客户端的鉴权,协议的 RFC 是这么说的:
This protocol doesn’t prescribe any particular way that servers can authenticate clients during the WebSocket handshake. The WebSocket server can use any client authentication mechanism available to a generic HTTP server, such as cookies, HTTP authentication, or TLS authentication.
也就是说,鉴权需要自己动手
二、协议原理
WebSocket 是独立的、创建在 TCP 上的协议。
为了创建 Websocket 连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”。
实现步骤
- 1)发起请求的浏览器端,发出协商报文
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Origin: http://example.com Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13
- 2)服务端响应 101 状态码(即切换到 socket 通讯方式),其报文:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= Sec-WebSocket-Protocol: chat
- 3)协议切换完成,双方使用 Socket 通讯
Require 内部逻辑(摘自官方文档)
当 Node 遇到
require(X)
时,按照下面的顺序处理。1)如果 X 是内置模块(比如
require('http')
)
- a.返回该模块
- b.不再继续执行
2)如果 X 以
./
或者../
开头
- a.根据 X 所在的父模块,确定 X 的绝对路径。
- b.将 X 当成文件,依次查找下面文件,只要其中有一个存在,就返回该文件,不再继续执行。(也就是把 X 跟下面的几种文件格式进行匹配,匹配到了就会依照相应的文件格式进行加载)
+----------------------+ | .x | | .x.js | | .x.json | | .x.node | +-------------------- +
- c.将 X 当成目录,一次查找下面文件,只要其中有一个存在,就返回该文件,不再继续执行。
+----------------------------+ | .X/package.json(main 字段) | | .X/index.js | | .X/index.json | | .X/index.node | +--------------------------- +
3)如果 X 不带路径
a.根据 X 所在的父模块,确定 X 可能的安装目录。 b.依次在每个目录中, 将 X 当成文件名或目录名加载
4)抛出 "not found"
误区
我们经常说 Get 请求参数的大小存在限制,而 Post 请求的参数大小是无限制的。
实际上 HTTP 协议从未规定 GET/POST 的请求长度限制是多少。对 Get 请求参数的限制是来源与浏览器或 web 服务器,浏览器或 web 服务器限制了 url 的长度。为了明确这个概念,我们必须再次强调下面几点:
- HTTP 协议未规定 GET 和 POST 的长度限制
- GET 的最大长度显示是因为浏览器和 web 服务器限制了 URI 的长度
- 不同的浏览器和 WEB 服务器,限制的最大长度不一样
- 要支持 IE,则最大长度为 2083byte,若只支持 Chrome,则最大长度 8182byte
Content-Type
Http 的实体首部字段,用于说明请求或返回的消息主体是用何种方式编码,在 request header 和 response header 里都存在。
几个常见的类型如下:
application/x-www-form-urlencoded
浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求如下面形式:
POST http://www.example.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded;charset=utf-8 title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
该种方式提交的数据放在 body 里面,数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。
multipart/form-data
该种方式也是一个常见的 POST 提交方式,通常表单上传文件时使用该种方式。
使用表单上传文件时,必须让 form 的 enctype 等于这个值。
<form action="/" method="post" enctype="multipart/form-data"> <input type="text" name="description" value="some text" /> <input type="file" name="myFile" /> <button type="submit">Submit</button> </form>
一、Reflect
ES6 提供了一个全新的 API-Reflect,Reflect 和 Proxy 是相对的,我们可以用 Reflect 操作对象。
1.1 Reflect 存在的意义
1)将 Object 对象一些内部的方法,放到 Reflect 对象上。比如 Object.defineProperty
现阶段这些方法存在于 object 和 Reflect 对象上,未来只存在于 Reflect 对象上。
意义:也就是说,从 Reflect 对象上可以拿到语言内部的方法。
- 2)操作对象时出现报错返回 false
比如:
Object.defineProperty(obj,name,desc)
在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj,name,desc)
则会返回 false,这样会更合理一些。// 旧写法 try { Object.defineProperty(target, property, attributes); } catch (err) { //failure } // 新写法 if (Reflect.defineProperty(target, property, attributes)) { //success } else { //failure }
- 3)让操作对象的编程变为函数式编程
说明:老写法有的是命令式编程,比如下面这个例子
// 老写法 "assign" in Object; // true // 新写法 Reflect.has(Object, "assign"); //true
- 4)保持和 Proxy 对象的方法一一对应
说明:Reflect 对象的方法与 Proxy 对象的方法一一对应,只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法。
Proxy(target, { set: function (target, name, value, receiver) { var success = Reflect.set(target, name, value, receiver); if (success) { console.log("property" + name + "on" + target + "set do " + value); } return success; }, });
这就让 Proxy 对象可以方便地调用对应的 Reflect 方法,完成默认行为,作为修改行为的基础。也就是说,不管 Proxy 怎么修改默认行为,你总可以在 Reflect 上获取默认行为。
综上所述:Reflect 对象有 4 个意义:
- 从 Reflect 对象上可以拿到语言内部的方法。
- 操作对象出现报错时返回 false
- 让操作对象都变为函数式编程
- 保持和 proxy 对象的方法一一对应