HTTP

HTTP是什么

  • 超文本传输协议,是一个客户端和服务器间通信必须遵守的协议,可用于传输文本、图片、音频视频等。
  • 建立在tcp/IP协议之上,依靠 IP协议实现寻址和路由、TCP 协议实现可靠数据传输、DNS 协议实现域名查找、SSL/TLS 协议实现安全通信。此外,还有一些协议依赖于 HTTP,例如 WebSocket 等。

HTTP报文

  • 请求行:请求方法/URI/HTTP版本
GET /index.html HTTP/1.1
  • 状态行:HTTP版本/状态码/状态信息
HTTP/1.1 200 OK
  • 头部字段,基本上可以分为四大类:
    通用字段:在请求头和响应头里都可以出现;
    请求字段:仅能出现在请求头里,进一步说明请求信息或者额外的附加条件;
    响应字段:仅能出现在响应头里,补充说明响应报文的信息;
    实体字段:它实际上属于通用字段,但专门描述 body 的额外信息。
  • 空行
  • 报文实体

请求方法

GET 获取资源 (常用)
POST 传输实体主体(常用)
PUT 传输文件
HEAD 获得报文首部(该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新)
DELETE 删除文件
OPTIONS 询问支持的方法

Get 与post的区别

1、传送方式:get通过地址栏传输,传的参数在地址栏可见,post通过报文传输数据。
2、传送长度:浏览器对get参数有长度限制(受限于url长度),而post无限制
3、请求缓存:GET 会被缓存,而post不会
4、收藏书签:GET可以,而POST不能
5、保存浏览器历史记录:GET可以,而POST不能

状态码

2XX 成功,操作被成功接收并处理
200 OK,表示从客户端发来的请求在服务器端被正确处理
204 No content,表示请求成功,但响应报文不含实体的主体部分
206 Partial content,表示请求成功,返回响应报文中包含由Content-Range指定范围的实体内容。
如果下载过程中遇到网络中断的情况,那就必须重头开始。因此指定下载的实体范围。请求首部Range:bytes=5001-10000,响应首部:Content-Range:bytes=5001-10000。如果服务器端无法响应范围请求,则会返回状态码200 OK和完整的实体内容。

3XX 重定向,需要进一步的操作以完成请求
301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
302 found,临时性重定向,表示资源临时被分配了新的 URL
304 not modified,该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304 Not Modified(服务器端资源未改变,可直接使用客户端未过期的缓存)。

4XX 客户端错误,请求包含语法错误或者无法完成请求
400 bad request,请求报文存在语法错误
401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
403 forbidden,表示对请求资源的访问被服务器拒绝
404 not found,表示在服务器上没有找到请求的资源
405 not allowed,方法不被允许,nginx上做了相关的配置

5XX 服务器错误,服务器在处理请求的过程中发生了错误
500 internal sever error,表示服务器端在执行请求时发生了错误
503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求

HTTP报文字段

实体字段
实体类型

URL 请求的数据类型,有时候是一个下载类型,有时候是正常的 HTML 页面,那么浏览器是如何区分它们呢?答案是 Content-Type。 它告诉浏览器服务器返回的响应体数据是什么类型,如果服务器配置 Content-Type 不正确,比如将 text/html 类型配置成 application/octet-stream 类型,那么浏览器可能会曲解文件内容,比如会将一个本来是用来展示的页面,变成了一个下载文件。

关于实体类型,请求头中用accept,响应头中用content,用于客户端和服务器进行“内容协商”。
Accept 字段标记的是客户端可理解的类型,在请求头中,如

Accept: text/html,application/xml,image/webp,image/png

conteng-type是服务端返回的文件类型,在响应头中,如

Content-Type: image/png

浏览器接受到文件类型就知道如何进行相应处理

常见的MINE Type有:

  • text:即文本格式的可读数据,我们最熟悉的应该就是 text/html 了,表示超文本文档,此外还有纯文本 text/plain、样式表 text/css 等。
  • image:即图像文件,有 image/gif、image/jpeg、image/png 等。
  • audio/video:音频和视频数据,例如 audio/mpeg、video/mp4 等。
  • application:数据格式不固定,可能是文本也可能是二进制,必须由上层应用程序来解释。常见的有 application/json,application/javascript、application/pdf 等,另外,如果实在是不知道数据是什么类型,像刚才说的“黑盒”,就会是 application/octet-stream,即不透明的二进制数据。
压缩类型

HTTP 在传输时为了节约带宽,有时候还会压缩数据,有一个“Encoding type”,告诉数据是用的什么编码格式,这样对方才能正确解压缩,还原出原始的数据。

Accept-Encoding 字段标记的是客户端可接受的压缩类型,在请求头中,如

Accept-Encoding: gzip, deflate, br

conteng-Encoding是服务端返回的文件的压缩类型,在响应头中,如

Content-Encoding: gzip

如果请求报文里没有 Accept-Encoding 字段,就表示客户端不支持压缩数据;如果响应报文里没有 Content-Encoding 字段,就表示响应数据没有被压缩。

常见的压缩类型(对文本文件有较好的压缩率):

  • gzip:最流行的压缩格式;
  • deflate:zlib(deflate)压缩格式,流行程度仅次于 gzip;
  • br:一种专门为 HTTP 优化的新压缩算法(Brotli)。
语言类型

Accept-Language 字段标记了客户端可理解的自然语言

Accept-Language: zh-CN, zh, en

Content-Language 告诉客户端实体数据使用的实际语言类型:

Content-Language: zh-CN
内容协商的质量值

Accept、Accept-Encoding、Accept-Language 等请求头字段进行内容协商的时候,还可以用一种特殊的“q”参数表示权重来设定优先级

Accept: text/html,application/xml;q=0.9,*/*;q=0.8

浏览器最希望使用的是 HTML 文件,权重是 1,其次是 XML 文件,权重是 0.9,最后是任意数据类型,权重是 0.8。服务器收到请求头后,就会计算权重,再根据自己的实际情况优先输出 HTML 或者 XML

通用字段
连接管理:Connection: keep-alive

短连接:客户端与服务器不会与服务器保持长时间的连接状态,请求发完后就断开连接,在 TCP 协议里, 建立连接要有“三次握手”,发送 3 个数据包,关闭连接是“四次挥手”,因此短连接很浪费资源。

长连接:也叫“持久连接”(persistent connections),既然 TCP 的连接和关闭非常耗时间,那么在HTTP请求-应答完成后不断开连接,继续发送HTTP请求,整体传输效率也就提高了。

因为 TCP 连接长时间不关闭,服务器必须在内存里保存它的状态,这就占用了服务器的资源。如果有大量的空闲长连接只连不发,就会很快耗尽服务器的资源,导致服务器无法为真正有需要的用户提供服务。

请求头和响应头都可以添加 Connection: keep-alive 要求长连接
在客户端,可以在请求头里加上“Connection: close”字段,告诉服务器:“这次通信后就关闭连接”。

服务器端通常不会主动关闭连接,但也可以使用一些策略。拿 Nginx 来举例,它有两种方式:

  • 使用“keepalive_timeout”指令,设置长连接的超时时间,如果在一段时间内连接上没有任何数据收发就主动断开连接,避免空闲连接占用系统资源。
  • 使用“keepalive_requests”指令,设置长连接上可发送的最大请求次数。比如设置成 1000,那么当 Nginx 在这个连接上处理了 1000 个请求后,也会主动断开连接。

“队头阻塞”
与短连接和长连接无关,而是由 HTTP 基本的“请求 - 应答”模型所导致的。因为 HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。队列里的请求没有轻重缓急的优先级,只有入队的先后顺序,排在最前面的请求被最优先处理。如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求也不得不跟着一起等待。

解决方法:
HTTP 协议和浏览器限制并发连接数量(chrome 上限6个),“域名分片”(domain sharding)技术,多开几个域名,比如 shard1.chrono.com、shard2.chrono.com,而这些域名都指向同一台服务器 www.chrono.com,这样实际长连接的数量就又上去了。

浏览器缓存: cache-control
  • max-age 是“生存时间”,max-age=5时间的计算起点是响应报文的创建时刻(即 Date 字段,也就是离开服务器的时刻),而不是客户端收到报文的时刻,也就是说包含了在链路传输过程中所有节点所停留的时间。比如,服务器设定“max-age=5”,但因为网络质量很糟糕,等浏览器收到响应报文已经过去了 4 秒,那么这个资源在客户端就最多能够再存 1 秒钟,之后就会失效。
  • no-store:不允许缓存,用于某些变化非常频繁的数据,例如秒杀页面;
  • no-cache:可以缓存,但在使用之前必须要去服务器验证是否过期,是否有最新的版本,有最新的版本就返回使用最新的版本,条件请求;
  • must-revalidate:它的意思是如果缓存不过期就可以继续使用,但过期了如果还想用就必须去服务器验证。

不止服务器可以发“Cache-Control”头,浏览器也可以发“Cache-Control”,也就是说请求 - 应答的双方都可以用这个字段进行缓存控制,互相协商缓存的使用策略。

  • 当你点“刷新”按钮的时候,浏览器会在请求头里加一个“Cache-Control: max-age=0”。
  • Ctrl+F5 :它其实是发了一个“Cache-Control: no-cache”

对于条件请求:cache-control:no-cache
第一次的响应报文预先提供“Last-modified”和“ETag”,然后第二次请求时就可以带上缓存里的原值,通过if-Modified-Since”和“If-None-Match验证资源是否是最新的。如果资源没有变,服务器就回应一个“304 Not Modified”,表示缓存依然有效,浏览器就可以更新一下有效期,然后放心大胆地使用缓存了。

ETag 是资源的一个唯一标识,主要是用来解决修改时间无法准确区分文件变化的问题。比如,一个文件在一秒内修改了多次,但因为修改时间是秒级,所以这一秒内的新版本无法区分。再比如,一个文件定期更新,但有时会是同样的内容,实际上没有变化,用修改时间就会误以为发生了变化,传送给浏览器就会浪费带宽。

请求字段
范围请求:Range:bytes=x-y( x 和 y 是以字节为单位)
cookie:token=123
响应字段
分块传输:Transfer-Encoding: chunked

报文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)逐个发送。“Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知(chunked)

范围请求:获取一个大文件其中的片段数据

响应头:Accept-Ranges: bytes
服务器必须在响应头里使用字段“Accept-Ranges: bytes”明确告知客户端:“我是支持范围请求的”。服务器可以发送“Accept-Ranges: none”,或者干脆不发送“Accept-Ranges”字段,这样客户端就认为服务器没有实现范围请求功能。

请求头 Range:bytes=x-y( x 和 y 是以字节为单位)

服务器收到 Range 字段后:
第一,它必须检查范围是否合法,如果范围越界了,服务器就会返回状态码 416。
第二,如果范围正确,服务器就可以根据 Range 头计算偏移量,读取文件的片段了,返回状态码“206 Partial Content”。
第三,服务器要添加一个响应头字段 Content-Range,告诉片段的实际偏移量和资源的总大小,格式是“bytes x-y/length”,例如,对于“0-10”的范围请求,值就是“bytes 0-10/100”。

请求:

GET /16-2 HTTP/1.1
Host: www.chrono.com
Range: bytes=0-31

响应:

HTTP/1.1 206 Partial Content
Content-Length: 32
Accept-Ranges: bytes
Content-Range: bytes 0-31/96

不仅看视频的拖拽进度需要范围请求,常用的下载工具里的多段下载、断点续传也是基于此实现,要点是:

  • 先发个 HEAD,看服务器是否支持范围请求,同时获取文件的大小;
  • 开 N 个线程,每个线程使用 Range 字段划分出各自负责下载的片段,发请求传输数据;
  • 下载意外中断也不怕,不必重头再来一遍,只要根据上次的下载记录,用 Range 请求剩下的那一部分就可以了。
重定向:Location

当访问一个地址时,如果服务端返回:

  • 301 永久重定向(Moved Permanently),浏览器看到 301,就知道原来的 URI“过时”了,就会做适当的优化。比如历史记录、更新书签,下次可能就会直接用新的 URI 访问,省去了再次跳转的成本。搜索引擎的爬虫看到 301,也会更新索引库,不再使用老的 URI。使用场景:例如域名变更、服务器变更等。
  • 302 临时重定向(“Moved Temporarily”),意思是原 URI 处于“临时维护”状态,新的 URI 是起“顶包”作用的“临时工”。系统维护转到通知页面
cookie设置:set-cookie

HTTP协议自身不具备保存之前发送过的请求或响应的功能,“无状态”

服务端通过set-cookie将相应的字段存储在浏览器cookie中,下次浏览器发出请求时就会将cookie里面的字段携带在请求头里面。

set-cookie字段
前端:

document.cookie = `tgc=${token};expires=${oDate.toGMTString()};path=/`

后端:

response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly")

生命周期:expires和Max-Age
“Expires”俗称“过期时间”,用的是绝对时间点。
如果Cookie没有设置expires属性,那么 cookie 的生命周期只是在当前的会话中,
关闭浏览器意味着这次会话的结束,此时 cookie 随之失效。

  • 当设置的失效时间大于等于1天时,我们可以在 expires 属性后面直接输入XX天数
  • 当设置的失效时间少于一天时:我们需要在当前的时间上加上失效时间
  • 如果expires设置一个过去的时间点,那么这个cookie 会被立即删掉(失效)。

“Max-Age”用的是相对时间,单位是秒,浏览器用收到报文的时间点(Date)再加上 Max-Age,就可以得到失效的绝对时间。

Expires 和 Max-Age 可以同时出现,两者的失效时间可以一致,也可以不一致,但浏览器会优先采用 Max-Age 计算失效期。

作用域:Domain和Path
让浏览器仅发送给特定的服务器和 URI,避免被其他网站盗用。

  • 在set-cookie中省略domain参数,那么domain默认为当前域名。
  • domain参数可以设置父域名以及自身,但不能设置其它域名,包括子域名,否则cookie不起作用。
  • cookie的作用域是domain本身以及domain下的所有子域名。

安全:HttpOnly、SameSite和Secure

  • HttpOnly:为防止跨站脚本攻击(Cross-site scripting,XSS)对Cookie的信息窃取,使用JavaScript的document.cookie就无法读写附加HttpOnly属性后的Cookie的内容。
  • “SameSite”:可以防范“跨站请求伪造”(XSRF)攻击,设置成“SameSite=Strict”可以严格限定 Cookie 不能随着跳转链接跨站发送,而“SameSite=Lax”则略宽松一点,允许 GET/HEAD 等安全方法,但禁止 POST 跨站发送。
  • “Secure”:表示这个 Cookie 仅能用 HTTPS 协议加密传输,明文的 HTTP 协议会禁止发送。但 Cookie 本身不是加密的,浏览器里还是以明文的形式存在。

URI

URI 主要有三个基本的部分构成:协议名:即访问该资源应当使用的协议,在这里是“http”;主机名:即互联网上主机的标记,可以是域名或 IP 地址,在这里是“nginx.org”;路径:即资源在主机上的位置,使用“/”分隔多级目录,在这里是“/en/download.html”。

TCP/IP

这个协议栈有四层,最上层是“应用层”,最下层是“链接层”,TCP 和 IP 则在中间:TCP 属于“传输层”,IP 属于“网际层”。
IP 协议是“Internet Protocol”的缩写,主要目的是解决寻址和路由问题,以及如何在两点间传送数据包。
TCP 协议是“Transmission Control Protocol”的缩写,意思是“传输控制协议”,它位于 IP 协议之上,基于 IP 协议提供可靠的、字节流形式的通信,是 HTTP 协议得以实现的基础。

DNS

但想要使用 TCP/IP 协议来通信仍然要使用 IP 地址,所以需要把域名做一个转换,“映射”到它的真实 IP,这就是所谓的“域名解析”

HTTPS

它的全称是“HTTP over SSL/TLS”,也就是运行在 SSL/TLS 协议上的 HTTP。

HTTP传输明文不安全,不具备以下四个特点:

  • 机密性:对数据的“保密”,只能由可信的人访问
  • 完整性:数据在传输过程中没有被篡改,保持着原状
  • 身份认证:确认对方的真实身份,保证消息只能发送给可信的人
  • 不可否认:不能否认已经发生过的行为

HTTPS的应答模式、报文结构、请求方法、URI、头字段、连接管理等等都完全沿用 HTTP,它把 HTTP 下层的传输协议由 TCP/IP 换成了 SSL/TLS,让 HTTP 运行在了安全的 SSL/TLS 协议上,收发报文不再使用 Socket API,而是调用专门的安全接口。

机密性保证

通过“密钥”对消息进行加密(key),加密前的消息叫“明文”(plain text/clear text),加密后的乱码叫“密文”(cipher text),使用密钥还原明文的过程叫“解密”(decrypt),是加密的反操作,加密解密的操作过程就是“加密算法”

对称加密:指加密和解密时使用的密钥都是同一个,是“对称”的。只要保证了密钥的安全,那整个通信过程就可以说具有了机密性。但如何把密钥安全地传递给对方,术语叫“密钥交换”,因此出现了非对称加密
非对称加密:有两个密钥,一个叫“公钥”(public key),一个叫“私钥”(private key)。两个密钥是不同的,公钥可以公开给任何人使用,而私钥必须严格保密。虽然都可以用来加密解密,但公钥加密后只能用私钥解密,反过来,私钥加密后也只能用公钥解密。非对称加密速度慢

混合加密
在通信刚开始的时候使用非对称算法,解决密钥交换的问题。用公钥加密对称算法使用的“会话密钥”。对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续就不再使用非对称加密,全都使用对称加密。

完整性保证

摘要算法可以理解成一种特殊的压缩算法,它能够把任意长度的数据“压缩”成固定长度、而且独一无二的“摘要”字符串,保证数据的完整性

真正的完整性必须要建立在机密性之上,在混合加密系统里用会话密钥加密消息和摘要,这样黑客无法得知明文,也就没有办法动手脚了

身份认证和不可否认

数字签名是私钥对摘要的加密,可以由公钥解密后验证,实现身份认证和不可否认;
公钥的分发需要使用数字证书,必须由 CA 的信任链来验证,否则就是不可信的;
(CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”)

HTTPS连接过程

HTTPS 协议会先与服务器执行 TCP 握手,然后执行 TLS 握手,才能建立安全连接;握手的目标是安全地交换对称密钥

HTTP2

HTTP2和HTTP1在很多方面保持一致,比如请求方法、URI、状态码、头字段等概念都保留不变,基于 HTTP 的上层应用也不需要做任何修改,可以无缝转换到 HTTP/2。HTTP/2 没有在 URI 里引入新的协议名,仍然用“http”表示明文协议,用“https”表示加密协议。

HTTP2在性能上有了很大的提升

头部压缩 因为头部字段多,体积挺大
HTTP/2 没有使用传统的压缩算法,而是开发了专门的“HPACK”算法,在客户端和服务器两端建立“字典”,用索引号表示重复的字符串,还釆用哈夫曼编码来压缩整数和字符串,可以达到 50%~90% 的高压缩率。
二进制格式和虚拟流报文二进制格式
把原来的“Header+Body”的消息“打散”为数个小片的二进制“帧”(Frame),流是二进制帧的双向传输序列,同一个消息往返的帧会分配一个唯一的流 ID。“数据流”是一串有先后顺序的数据帧,这些数据帧按照次序组装起来就是 HTTP/1 里的请求报文和响应报文。因为“流”是虚拟的,实际上并不存在,所以 HTTP/2 就可以在一个 TCP 连接上用“流”同时发送多个“碎片化”的消息,这就是常说的“多路复用”( Multiplexing)——多个往返通信都复用一个连接来处理。在“流”的层面上看,消息是一些有序的“帧”序列,而在“连接”的层面上看,消息却是乱序收发的“帧”。多个请求 / 响应之间没有了顺序关系,不需要排队等待,也就不会再出现“队头阻塞”问题,降低了延迟,大幅度提高了连接的利用率。

CDN

CDN它就是专门为解决“长距离”上网络访问速度慢而诞生的一种网络应用服务。它可以缓存源站的数据,让浏览器的请求不用“千里迢迢”地到达源站服务器,直接在“半路”就可以获取响应。

只有静态资源才能够被缓存加速、就近访问,而动态资源只能由源站实时生成,即使缓存了也没有意义。不过,如果动态资源指定了“Cache-Control”,允许缓存短暂的时间,那它在这段时间里也就变成了“静态资源”,可以被 CDN 缓存加速

就近访问
全局负载均衡:主要的职责是当用户接入网络的时候在 CDN 专网中挑选出一个“最佳”节点提供服务,解决的是用户如何找到“最近的”边缘节点

原来没有 CDN 的时候,权威 DNS 返回的是网站自己服务器的实际 IP 地址,浏览器收到 DNS 解析结果后直连网站。但加入 CDN 后就不一样了,权威 DNS 返回的不是 IP 地址,而是一个 CNAME( Canonical Name ) 别名记录,指向的就是 CDN 的 GSLB。

因为没拿到 IP 地址,于是本地 DNS 就会向 GSLB 再发起请求,这样就进入了 CDN 的全局负载均衡系统,开始“智能调度”,主要的依据有这么几个:

  • 看用户的 IP 地址,查表得知地理位置,找相对最近的边缘节点
  • 看用户所在的运营商网络,找相同网络的边缘节点;
  • 检查边缘节点的负载情况,找负载较轻的节点;
  • 其他,比如节点的“健康状况”、服务能力、带宽、响应时间等。

GSLB 把这些因素综合起来,用一个复杂的算法,最后找出一台“最合适”的边缘节点,把这个节点的 IP 地址返回给用户,用户就可以“就近”访问 CDN 的缓存代理了。
缓存
“命中”就是指用户访问的资源恰好在缓存系统里,可以直接返回给用户;“回源”则正相反,缓存里没有,必须用代理的方式回源站取。

WAF

“网络应用防火墙”,WAF 通常位于 Web 服务器之前。

网络攻击种类
DDoS攻击黑客控制许多“僵尸”计算机,向目标服务器发起大量无效请求。因为服务器无法区分正常用户和黑客,只能“照单全收”,这样就挤占了正常用户所应有的资源。如果黑客的攻击强度很大,就会耗尽带宽、CPU 和内存,导致网站完全无法提供正常服务。
SQL 注入利用了服务器字符串拼接形成 SQL 语句的漏洞,构造出非正常的 SQL 语句,获取数据库内部的敏感信息。
HTTP 头注入在“Host”“User-Agent”“X-Forwarded-For”等字段里加入了恶意数据或代码,服务端程序如果解析不当,就会执行预设的恶意代码。
跨站脚本利用 JavaScript 脚本获取未设防的 Cookie。

websocket

WebSocket 采用了二进制帧结构,语法、语义与 HTTP 完全不兼容。

WebSocket 也要有一个握手过程,然后才能正式收发数据。利用HTTP 本身的“协议升级”特性,“伪装”成 HTTP,这样就能绕过浏览器沙盒、网络防火墙等等限制。WebSocket 的握手是一个标准的 HTTP GET 请求,但要带上两个协议升级的专用头字段:“Connection: Upgrade”,表示要求协议“升级”;“Upgrade: websocket”,表示要“升级”成 WebSocket 协议。服务器于是就不走普通的 HTTP 处理流程,而是构造一个特殊的“101 Switching Protocols”响应报文,通知客户端,接下来就不用 HTTP 了,全改用 WebSocket 协议通信。

HTTP 的“请求 - 应答”模式不适合开发“实时通信”应用,所以出现了 WebSocket;
WebSocket 是一个“全双工”的通信协议,相当于对 TCP 做了一层“薄薄的包装”,让它运行在浏览器环境里;
WebSocket 使用兼容 HTTP 的 URI 来发现服务,但定义了新的协名“ws”和“wss”,端口号也沿用了 80 和 443;
WebSocket 利用 HTTP 协议实现连接握手,发送 GET 请求要求“协议升级”,握手过程中有个非常简单的认证机制,目的是防止误连接。

跨域控制

缓存

浏览器缓存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值