Appearance
常见状态码
1XX:通知2XX:成功3XX:重定向4XX:客户端错误5XX:服务端错误
常见响应代码:
- 200("OK"):一切正常
- 301("Moved Permanently"):当客户端触发的动作引起了资源URI的变化时发送此响应代码
- 304("Not Modified"):服务端内容未变更,客户端缓存可继续使用
- 400("Bad Request"):通用的客户端错误状态,当其他 4XX 响应代码不适用时,就采用 400。此响应代码通常用于「服务器收到客户端通过 PUT 或者 POST 请求提交的表示,表示的格式正确,但服务器不懂它什么意思」的情况。
- 401("Unauthorized"):客户端提供了错误的证书,或者根本没有提供证书
- 403("Forbidden"):客户端请求的结构正确,但是服务器不想处理它
- 404("Not Found"):当客户端所请求的 URI 不对应于任何资源时,发送此响应代码
- 500("Internal Server Error"):通用的服务器错误响应,对于大多数web框架,如果在执行请求处理代码时遇到了异常,它们就发送此响应代码
- 502("Bad Gateway"):只有 HTTP 代理会发送这个响应代码。它表明代理方面出现问题,或者代理与上行服务器之间出现问题,而不是上行服务器本身有问题
- 503("Service Unavailable"):此响应代码表明 HTTP 服务器正常,只是下层 web 服务服务不能正常工作。最可能的原因是资源不足(服务器突然收到太多请求,以至于无法全部处理)
- 504("Gateway Timeout"):跟 502 类似,只有 HTTP 代理会发送此响应代码,此响应代码表明代理无法连接上行服务器
缓存
浏览器缓存策略分为两种:强缓存和协商缓存。
强缓存:
强缓存的几个位置:Memory Cache, Disk Cache, Push Cache, Service Worker
实现强缓存可以通过两种响应头实现:Expires 和 Cache-Control。强缓存表示在缓存期间不需要请求,state code 为 200
Expires: Wed, 22 Oct 2018 08:41:00 GMTExpires 是 HTTP / 1.0 的产物,表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT 后过期,需要再次请求。并且 Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。
Cache-control: max-age=30s-max-age: 同 max-age,但仅用于共享缓存(如代理)
Cache-Control 出现于 HTTP / 1.1,优先级高于 Expires。该属性表示资源会在 30 秒后过期,需要再次请求。
协商缓存:
如果缓存过期了,我们就可以使用协商缓存来解决问题。协商缓存需要请求,如果缓存有效会返回 304。
协商缓存需要客户端和服务端共同实现,和强缓存一样,也有两种实现方式。
Last-Modified 和 If-Modified-Since
Last-Modified 表示本地文件最后修改日期,If-Modified-Since 会将 Last-Modified 的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来。
但是如果在本地打开缓存文件,就会造成 Last-Modified 被修改,所以在 HTTP / 1.1 出现了 ETag。
ETag 和 If-None-Match
ETag 类似于文件指纹,If-None-Match 会将当前 ETag 发送给服务器,询问该资源 ETag 是否变动,有变动的话就将新的资源发送回来。并且 ETag 优先级比 Last-Modified 高。
既生 Last-Modified 何生 Etag?
你可能会觉得使用 Last-Modified 已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要 Etag 呢?HTTP1.1 中 Etag 的出现主要是为了解决几个 Last-Modified 比较难解决的问题:
- 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新 GET
- 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since 能检查到的粒度是 s 级的,这种修改无法判断(或者说 UNIX 记录 MTIME 只能精确到秒)
- 某些服务器不能精确的得到文件的最后修改时间
这时,利用 Etag 能够更加准确的控制缓存,因为 Etag 是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符。
Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。
选择合适的缓存策略
对于大部分的场景都可以使用强缓存配合协商缓存解决,但是在一些特殊的地方可能需要选择特殊的缓存策略:
- 对于某些不需要缓存的资源,可以使用
Cache-control: no-store,表示该资源不需要缓存 - 对于频繁变动的资源,可以使用
Cache-Control: no-cache并配合ETag使用,表示该资源已被缓存,但是每次都会发送请求询问资源是否更新。 - 对于代码文件来说,通常使用
Cache-Control: max-age=31536000并配合策略缓存使用,然后对文件进行指纹处理,一旦文件名变动就会立刻下载新的文件
请求时浏览器缓存 from memory cache 和 from disk cache 的依据是什么,哪些数据什么时候存放在 Memory Cache 和 Disk Cache中?
Memory Cache 是内存中的缓存,在内存中读取缓存速度快,读取高效,但是持续性很短,会跟随进程的释放而释放。
浏览器也是运行的时候是由几个进程协作的,所以操作系统为了节省内存,会把一部分内存里的资源交换回磁盘的交换区,当然交换是有策略的,比如最常用的就是LRU。所以缓存资源不过期的时候,如果资源在内存那么就from memory,如果只有在磁盘上就from disk。
参考资料
DNS 是怎么解析的
DNS 是应用层协议,事实上他是为其他应用层协议工作的,包括不限于 HTTP 和 SMTP 以及 FTP,用于将用户提供的主机名解析为 IP 地址。大致过程如下:
- 用户主机上运行着 DNS 的客户端(就是我们的 PC 机或者手机客户端运行着 DNS 客户端)
- 浏览器将接收到的 URL 中抽取出域名字段,就是访问的主机名,比如:
http://www.baidu.com/,并将这个主机名传送给 DNS 应用的客户端 - DNS 客户机端向 DNS 服务器端发送一份查询报文,报文中包含着要访问的主机名字段(中间包括一些缓存查询以及分布式 DNS 集群的工作)
- 该 DNS 客户机最终会收到一份回答报文,其中包含有该主机名对应的 IP 地址
- 一旦浏览器收到来自 DNS 的 IP 地址,就可以向该 IP 地址定位的 HTTP 服务器发起 TCP 连接
参考资料
- (DNS解析的过程是什么,求详细的?)[https://www.zhihu.com/question/23042131]
CDN
CDN 全称:Content Delivery Network 或 Content Ddistribute Network,即内容分发网络
其目的是解决因分布、带宽、服务器性能带来的访问延迟问题,使内容传输的更快、更稳定。
通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN 系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。
静态资源尽量使用 CDN 加载,由于浏览器对于单个域名有并发请求上限,可以考虑使用多个 CDN 域名。对于 CDN 加载静态资源需要注意 CDN 域名要与主站不同,否则每次请求都会带上主站的 Cookie。
参考资料
- (CDN是什么?使用CDN有什么优势?)[https://www.zhihu.com/question/36514327]
计算机网络的相关协议
UDP, TCP, HTTP, HTTPS, HTTP2.0, DNS
http/https/http2.0
HTTP,全称超文本传输协议(HTTP,HyperText Transfer Protocol),是一个客户端和服务器端请求和应答的标准(TCP),互联网上应用最为广泛的一种网络协议。客户端是终端用户,服务器端是网站。通过使用 Web 浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的 HTTP 请求。
HTTPS,即加密后的 HTTP。HTTP 协议传输的数据都是未加密的,也就是明文的,因此使用 HTTP 协议传输隐私信息非常不安全。HTTPS 都是用的 TLS 协议,但是由于 SSL 出现的时间比较早,并且依旧被现在浏览器所支持,因此 SSL 依然是 HTTPS 的代名词,但无论是 TLS 还是 SSL 都是上个世纪的事情,SSL 最后一个版本是3.0,今后 TLS 将会继承 SSL 优良血统继续为我们进行加密服务。目前 TLS 的版本是 1.2,定义在 RFC5246 中,暂时还没有被广泛的使用。
HTTP2.0,下一代的 HTTP 协议。相比于 HTTP1.x,大幅度的提升了 web 性能,进一步减少了网络延时和拥塞。
HTTP 报文分析:
请求报文:
- 请求行 请求行由「方法字段,URL 字段,HTTP 协议版本」字段 3 个部分组成,他们之间使用空格隔开。常用的 HTTP 请求方法有
GET,POST,HEAD,PUT,DELETE,OPTIONS,TRACE,CONNECT。 - 请求头部 请求头部由「关键字/值」对组成,每行一对,关键字和值用英文冒号
:分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:User-Agent:产生请求的浏览器类型Accept:客户端可识别的响应内容类型列表。星号*用于按范围将类型分组,用/指示可接受全部类型,用type/*指示可接受 type 类型的所有子类型Accept-Language:客户端可接受的自然语言Accept-Encoding:客户端可接受的编码压缩格式Accept-Charset:可接受的应答的字符集Host:请求的主机名,允许多个域名同处一个 IP 地址,即虚拟主机connection:连接方式(close/keepalive),如果是close的话就需要进行 TCP 四次挥手关闭连接,如果是keepalive,表明还能继续使用,这是 HTTP1.1 对 1.0 的新增,加快了网络传输,默认是keepaliveCookie:存储于客户端扩展字段,向同一域名的服务端发送属于该域的 cookie
- 空行 最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头
- 请求包体 请求包体不在 GET 方法中使用,而是在 POST 方法中使用。POST 方法适用于需要客户填写表单的场合。与请求包体相关的最常使用的是包体类型 Content-Type 和包体长度 Content-Length
响应报文:
- 状态行 状态行由「HTTP 协议版本字段,状态码,状态码的描述文本」3 个部分组成,他们之间使用空格隔开,描述文本一般不显示
- 响应头部 响应头可能包括:
Location:Location响应报头域用于重定向接受者到一个新的位置。例如:客户端所请求的页面已不存在原先的位置,为了让客户端重定向到这个页面新的位置,服务器端可以发回Location响应报头后使用重定向语句,让客户端去访问新的域名所对应的服务器上的资源Server:Server响应报头域包含了服务器用来处理请求的软件信息及其版本。它和User-Agent请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户端软件(浏览器)和操作系统的信息Vary:指示不可缓存的请求头列表Connection:连接方式,这个跟 rquest 的类似
- 空行:最后一个响应头部之后是一个空行,发送回车符和换行符,通知服务器以下不再有响应头部
- 响应包体:服务器返回给客户端的文本信息
HTTP 特性:
- 无状态性:当客户端访问完一次服务器再次访问的时候,服务器是无法知道这个客户端之前是否已经访问过了
- 持久连接:服务器在发送响应后仍然在一段时间内保持这条连接,允许在同一个连接中存在多次数据请求和响应
- 其它:支持客户/服务器模式、简单快速(请求方法简单 GET, POST)、灵活(数据对象任意)
影响 HTTP 的因素
- 带宽
- 延迟(浏览器阻塞、DNS 查询、TCP 连接建立等)
HTTP 缺陷
- 耗时:传输数据每次都要建立连接
- 不安全:HTTP是明文传输的,只要在路由器或者交换机上截取,所有东西(账号密码)都是可见的;
- Header 内容过大:通常,客户端的请求 header 变化较小,但是每次都要携带大量的 header 信息,导致传输成本增大
- keepalive 压力过大:持久连接虽然有一点的优点,但同时也会给服务器造成大量的性能压力,特别是传输图片的时候
HTTPS
由于HTTP报文的不安全性,网景在1994年就创建了HTTPS,并用在浏览器中。最初HTTPS是和SSL一起使用,然后演化为TLS。SSL/TLS在OSI模型中都是表示层的协议。SSL使 用40 位关键字作为RC4流加密算法,这对于商业信息的加密是合适的。
HTTP2.0
HTTP2.0,相较于HTTP1.x,大幅度的提升了web性能。在与HTTP/1.1完全语义兼容的基础上,进一步减少了网络延迟和传输的安全性。
相较于 HTTP1.1,HTTP2.0 的主要优点有:
- 采用二进制帧封装
- 传输变成多路复用
- 流量控制算法优化
- 服务器端推送
- 支持首部压缩
- 优先级等特点
参考资料
get, post 区别
首先最直观的是语义上的区别。
而后又有这样一些具体的差别:
- 从缓存的角度,GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。
- 从编码的角度,GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
- 从参数的角度,GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
- 从幂等性的角度,GET 是幂等的,而 POST 不是。(幂等表示执行相同的操作,结果也是相同的)
- 从 TCP 的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
参考资料:
TCP 三次握手,四次挥手流程
建立连接三次握手:
- 第一次握手:客户端向服务端发送连接请求报文段。该报文段中包含自身的数据通讯初始序号。请求发送后,客户端便进入
SYN-SENT状态,x 表示客户端的数据通信初始序号 - 第二次握手:服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入
SYN-RECEIVED状态 - 当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。客户端发完这个报文段后便进入
ESTABLISHED状态,服务端收到这个应答后也进入ESTABLISHED状态,此时连接建立成功
四次挥手关闭连接:
- 第一次挥手:若客户端 A 认为数据发送完成,则它需要向服务端 B 发送连接释放请求
- 第二次挥手:B 收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入
CLOSE_WAIT状态,表示 A 到 B 的连接已经释放,不接收 A 发的数据了。但是因为 TCP 连接是双向的,所以 B 仍旧可以发送数据给 A - 第三次挥手:B 如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入
LAST-ACK状态 - 第四次挥手:A 收到释放请求后,向 B 发送确认应答,此时 A 进入
TIME-WAIT状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃)时间,若该时间段内没有 B 的重发请求的话,就进入CLOSED状态。当 B 收到确认应答后,也便进入CLOSED状态
TCP 为什么可靠?
TCP 的可靠保证,是它的三次握手双向机制,这一机制保证校验了数据,保证了他的可靠性。而 UDP 就没有了,UDP 信息发出后,不验证是否到达对方,所以不可靠。不过 UDP 的速度是 TCP 比不了的,而且 UDP 的反应速度更快,QQ 就是用 UDP 协议传输的,HTTP 是用 TCP 协议传输的。
参考资料:
- (TCP 状态机)[https://yuchengkai.cn/docs/cs/#状态机]
websocket
WebSocket 是双向的,在客户端-服务器通信的场景中使用的全双工协议,与 HTTP 不同,它以 ws:// 或 wss:// 开头。它是一个有状态协议,这意味着客户端和服务器之间的连接将保持活动状态,直到被任何一方(客户端或服务器)终止。在通过客户端和服务器中的任何一方关闭连接之后,连接将从两端终止。
Http 请求中的 keep-alive 有了解吗
HTTP 持久连接(HTTP persistent connection,也称作 HTTP keep-alive 或 HTTP connection reuse,翻译过来可以是保持连接或者连接复用)是使用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,而不是为每一个新的请求/应答打开新的连接的方式。
HTTP 协议采用「请求-应答」模式,当使用普通模式,即非 KeepAlive 模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP 协议为无连接的协议),每次请求都会经过三次握手四次挥手过程,效率较低;当使用 Keep-Alive 模式时,客户端到服务器端的连接不会断开,当出现对服务器的后继请求时,客户端就会复用已建立的连接。
参考资料:
网络分层
网络为什么要分层?
为了简化网络设计的复杂性,通信协议采用分层的结构,各层协议之间既相互独立又相互高效的协调工作。对于复杂的通信协议,其结构应该是采用层次的。分层的协议可以带来很多便利:
- 灵活性好:当任何一层发生变化时,只要层间接口关系保持不变,则在这层以上或以下各层均不受影响。此外,对某一层提供的服务还可进行修改。当某层提供的服务不再需要时,甚至可以将这层取消,更容易管理
- 各层之间是独立的:在各层间标准化接口,允许不同的产品只提供各层功能的一部分,某一层不需要知道它的下一层是如何实现的,而仅仅需要知道该层通过层间的接口所提供的服务。由于每一层只实现一种相对独立的功能,所以比较容易实现
业内普遍的分层方式有两种,OSI 七层模型 和 TCP/IP 四层模型:
**OSI七层模型:**物、数、网、传、会、表、应(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层)
**TCP/IP四层模型:**链、网、传、应(链路层、网络层、传输层、应用层)
- (网络分层架构(七/四层协议))[https://blog.csdn.net/qq_38560742/article/details/88398270]
TCP 和 UDP 相比的话,UDP 有什么好处,虽然不可靠,但是为什么还有很多基于 UDP 的协议?
因为 UDP 报文小,UDP 头部 8 个字节,TCP 头部 20 个字节,而且有些协议也不需要太可靠
UDP: QQ语音、QQ视频
HTTP 请求的方法有哪几种?HEAD 请求是干什么的?
GET, POST, PUT, DELETE, HEAD, OPTIONS
HEAD 和 GET 本质是一样的,区别在于 HEAD 不含有呈现数据,而仅仅是 HTTP 头信息。有的人可能觉得这个方法没什么用,其实不是这样的。想象一个业务情景:欲判断某个资源是否存在,我们通常使用 GET,但这里用 HEAD 则意义更加明确。
POST 提交数据的方式有哪几种?
application/x-www-form-urlencodedapplication/form-dataapplication/jsonapplication/xml- ...
multipart/form-data 与 x-www-form-urlencoded 区别:
html 中的 form 表单有两种:application/x-www-form-urlencoded 和 multipart/form-data。application/x-www-form-urlencoded 是默认的 MIME 内容编码类型,它在传输比较大的二进制或者文本数据时效率极低。
multipart/form-data:既可以上传文件等二进制数据,也可以上传表单键值对,只是最后会转化为一条信息x-www-form-urlencoded:只能上传键值对,并且键值对都是间隔分开的
参考资料:
什么是 RESTful?
所谓的 RESTful 就是用来规范我们的 API 的一种约束。
作为 REST,其实是 Representational State Transfer(表象层状态转变)三个单词的缩写,它由 Roy Fielding 于 2000 年论文中提出,它代表着分布式服务的架构风格。
简单来说,就是:用 URL 定位资源,用 HTTP 动词(GET: 获取, POST: 新建, DELETE: 删除, PUT: 更新)描述操作
对前端最显著的好处就是接口数量会少很多,比如针对 user 的增删改查,只要一个接口定义四种请求方式 .post(user), .delete(user), .put(user), .get(user) 即可,而不用定义四个接口。
