浏览器与网络
1.GET
与 POST
请求有什么区别?
GET
和 POST
是 HTTP 协议中常用的两种请求方法,它们之间有一些关键区别:
请求目的:
GET
:用于请求资源。通常用于从服务器获取数据而不修改服务器的状态。POST
:用于提交数据。通常用于将数据发送到服务器,可能导致服务器状态的变化,比如创建或更新资源。
请求参数的位置:
GET
:参数包含在 URL 中,作为查询字符串(如:/path?key=value
),直接显示在地址栏中。POST
:参数包含在请求体中,不显示在 URL 上,因此在一定程度上保护了数据的隐私。
安全性:
GET
:由于参数显示在 URL 中,数据容易被记录在浏览历史和日志中,适合传输非敏感数据。POST
:数据存放在请求体内,虽然仍然可以被截获,但在日志中不会显示敏感信息,因此更适合传输敏感数据。
请求长度:
GET
:URL 长度受限制(取决于浏览器和服务器的实现),不适合传输大量数据。POST
:没有严格的长度限制,适合传输大量数据或复杂数据结构。
幂等性:
GET
:通常是幂等的,多次请求相同的GET
会得到相同的结果,不影响服务器状态。POST
:通常不是幂等的,多次请求相同的POST
可能导致数据重复创建或状态变化。
缓存:
GET
:可以被浏览器缓存,因此通常适合用于获取静态内容。POST
:通常不会被浏览器缓存,因此更适合需要确保新数据的请求。
总结:GET
请求适用于获取资源数据,而 POST
请求则适用于提交数据和对服务器资源进行更新或创建。
2. HTTP2
相对于 HTTP1.x
有什么优势和特点?
HTTP/2 是 HTTP 协议的改进版本,相较于 HTTP/1.x 提供了许多优势和优化,主要包括以下特点:
二进制分帧:
- HTTP/2 使用二进制格式传输数据,而非 HTTP/1.x 的纯文本格式。这种方式更易于解析,减少了传输数据的歧义性。
多路复用:
- HTTP/2 支持多路复用,允许多个请求和响应在同一 TCP 连接中并行传输,解决了 HTTP/1.x 中队头阻塞的问题。这显著提升了网络资源的利用率和响应速度。
头部压缩:
- HTTP/2 使用
HPACK
算法对头部信息进行压缩,并缓存重复的头部,减少了传输的头部大小,从而降低带宽占用,减少延迟。
- HTTP/2 使用
服务器推送:
- 服务器可以在客户端请求前主动推送资源,避免了客户端等待所需资源的延迟。这对资源加载的性能优化非常有帮助,特别是在网页上包含多个静态资源的情况下。
流优先级和依赖关系:
- HTTP/2 支持对不同请求设置优先级,使重要资源优先加载,提高页面的加载体验。客户端可以指定某些流的优先级和依赖关系,从而优化资源的传输顺序。
更好的安全性:
- 虽然 HTTP/2 并不强制使用加密传输,但大多数主流浏览器只在 HTTPS 上支持 HTTP/2,使得数据传输更加安全。
HTTP/2 优势总结
- 性能提升:多路复用、头部压缩和服务器推送等特性减少了传输延迟,加快了页面加载速度。
- 资源优化:通过优先级和依赖关系设置,使得资源加载顺序更加合理。
- 带宽节省:头部压缩减少了数据传输量,提高了带宽利用率。
总结:HTTP/2 在传输效率和资源优化方面优于 HTTP/1.x,使得网页加载速度更快、带宽利用率更高、用户体验更好。
3. HTTPS 是如何保证安全的,为什么比 HTTP 更安全?
HTTPS(HyperText Transfer Protocol Secure)是在 HTTP 协议的基础上增加了 SSL/TLS 加密层,用于实现安全的数据传输。相比 HTTP,HTTPS 主要通过以下方式提升了安全性:
1. 数据加密
- HTTPS 使用 SSL/TLS 协议加密传输数据,避免了 HTTP 明文传输的风险。即使数据在传输过程中被截获,攻击者也无法轻易解读内容,有效保护了敏感信息(如密码、个人信息等)。
2. 数据完整性
- SSL/TLS 采用消息验证码(MAC)技术,确保数据在传输过程中未被篡改。每个数据包在发送前会生成校验码,接收方通过校验码判断数据的完整性,确保数据未被中途修改。
3. 身份验证
- HTTPS 使用数字证书验证服务器的身份,确保用户访问的是合法的服务器。服务器必须提供经过认证机构(CA)签发的证书,客户端会验证证书的合法性,防止用户被重定向到恶意服务器。
4. 防止中间人攻击
- 通过加密和身份验证,HTTPS 有效防止了中间人攻击。攻击者即使拦截了数据包,也无法伪装成服务器或解密数据,从而确保客户端和服务器之间通信的安全性。
HTTPS 与 HTTP 安全性的比较
- 加密性:HTTP 以明文传输数据,容易被拦截和窃取,而 HTTPS 对传输数据进行加密保护。
- 身份验证:HTTP 缺乏身份验证机制,容易被伪装,而 HTTPS 通过数字证书保证了服务器身份的真实性。
- 数据完整性:HTTP 无法保证数据完整性,数据可能被中途篡改;而 HTTPS 通过消息验证码(MAC)机制确保数据未被更改。
总结
HTTPS 通过加密传输、身份验证和数据完整性等手段,使得数据传输过程更安全。相比 HTTP,HTTPS 能有效保护用户隐私,防止数据被窃取和篡改。
4. HTTP 的状态码有哪些?并代表什么意思?
HTTP 状态码用于表示服务器对客户端请求的响应状态,分为五类:1xx、2xx、3xx、4xx 和 5xx。以下是每类状态码的详细说明及常见状态码的解释:
1xx - 信息性状态码
表示请求已接收,继续处理。
- 100 Continue:请求已部分完成,客户端可以继续请求,或忽略此状态码。
- 101 Switching Protocols:服务器接受客户端协议切换的请求,正在切换协议。
- 102 Processing:请求正在处理,避免客户端超时。
2xx - 成功状态码
表示请求已成功处理。
- 200 OK:请求成功,服务器已返回所请求的资源。
- 201 Created:请求成功,服务器创建了新资源(常用于 POST 请求)。
- 202 Accepted:请求已接受,但尚未处理(通常用于异步处理)。
- 203 Non-Authoritative Information:请求成功,但返回的内容非服务器的原始数据(例如代理服务器修改后返回的内容)。
- 204 No Content:请求成功,但服务器未返回内容,通常用于更新操作。
- 205 Reset Content:请求成功,要求客户端重置视图(例如表单清除)。
- 206 Partial Content:请求成功,返回了部分内容(用于分块下载或视频流)。
3xx - 重定向状态码
表示客户端需执行进一步操作完成请求。
- 300 Multiple Choices:请求资源存在多个表示,需客户端选择(例如不同格式)。
- 301 Moved Permanently:请求的资源已永久移动到新位置,使用新 URL。
- 302 Found:请求资源临时移动,客户端应使用新 URL。
- 303 See Other:请求资源需使用
GET
方法访问新的 URL。 - 304 Not Modified:资源未修改,客户端可使用缓存版本。
- 307 Temporary Redirect:请求资源临时移动,使用相同方法访问新 URL。
- 308 Permanent Redirect:资源已永久移动,客户端应使用新 URL 进行后续请求。
4xx - 客户端错误状态码
表示客户端请求有误,需更正后再试。
- 400 Bad Request:请求格式错误,服务器无法理解。
- 401 Unauthorized:请求未授权,需提供有效身份验证(例如 JWT 令牌)。
- 402 Payment Required:保留状态码,现用于一些特定场景(如支付系统)。
- 403 Forbidden:服务器拒绝请求,客户端无访问权限。
- 404 Not Found:请求的资源不存在或服务器未找到资源。
- 405 Method Not Allowed:请求方法不支持(例如
GET
请求用于POST
资源)。 - 406 Not Acceptable:请求资源的格式不符合客户端
Accept
头要求。 - 407 Proxy Authentication Required:需通过代理进行身份验证。
- 408 Request Timeout:请求超时,服务器等待请求时超时。
- 409 Conflict:请求资源状态冲突(例如并发编辑冲突)。
- 410 Gone:资源已永久删除,服务器无资源。
- 411 Length Required:服务器要求客户端在请求头中指定
Content-Length
。 - 412 Precondition Failed:请求头中条件不满足,无法完成请求。
- 413 Payload Too Large:请求数据量大于服务器允许值。
- 414 URI Too Long:请求 URI 长度超过服务器允许。
- 415 Unsupported Media Type:请求的媒体类型不受支持。
- 416 Range Not Satisfiable:请求范围无效,服务器无法提供。
- 417 Expectation Failed:
Expect
请求头的条件未满足。
5xx - 服务器错误状态码
表示服务器处理请求出错,无法完成请求。
- 500 Internal Server Error:服务器内部错误,未能完成请求。
- 501 Not Implemented:服务器不支持请求方法。
- 502 Bad Gateway:服务器作为网关,收到无效响应。
- 503 Service Unavailable:服务器超负载或维护中,暂时无法处理请求。
- 504 Gateway Timeout:服务器作为网关,未及时获得上游服务器响应。
- 505 HTTP Version Not Supported:请求 HTTP 版本不支持。
- 506 Variant Also Negotiates:服务器内部配置错误,导致循环请求。
- 507 Insufficient Storage:服务器无法存储请求所需的数据。
- 508 Loop Detected:服务器检测到循环请求,导致死循环。
- 510 Not Extended:客户端需进一步扩展请求(例如指定协议)。
- 511 Network Authentication Required:客户端需认证才能访问网络。
总结
HTTP 状态码通过分类和具体描述,帮助客户端了解请求结果和问题所在,使得客户端能够采取适当措施进行处理。
5. 聊聊对options
预检请求的理解
当使用 POST
请求跨域访问资源时,浏览器会先发送一个 OPTIONS
请求。这种请求称为 预检请求(Preflight Request),它用于确认服务器是否允许跨域请求,确保请求的安全性。预检请求的主要原因和机制如下:
1. 跨域资源共享(CORS)机制
为了防止潜在的安全问题,浏览器对跨域请求进行了严格限制。跨域资源共享(CORS, Cross-Origin Resource Sharing)是浏览器的一个安全机制,用来确定服务器是否允许跨域访问。
- 当请求包含自定义头部或使用了除
GET
、HEAD
、POST
以外的 HTTP 方法时(例如PUT
、DELETE
),浏览器会发起一个OPTIONS
预检请求。 OPTIONS
请求会询问服务器是否允许客户端执行该跨域请求,并通过服务器返回的响应头来确认权限。
2. 预检请求的触发条件
浏览器会对特定条件的请求触发预检请求,包括以下几种情况:
- 请求方法:使用了
POST
、PUT
、DELETE
等会影响服务器状态的请求方法(除了GET
和HEAD
)。 - 请求头:使用了非简单请求头(如自定义
Authorization
、Content-Type
等)。 - 数据类型:
POST
请求发送的数据类型不属于application/x-www-form-urlencoded
、multipart/form-data
或text/plain
这三种简单类型。
3. 预检请求的作用
预检请求的主要目的是让服务器验证和告知客户端是否允许此类跨域请求。服务器响应的头部会告知客户端一些权限信息,包括:
- Access-Control-Allow-Origin:允许的源(域名)。
- Access-Control-Allow-Methods:允许的请求方法(如
POST
、PUT
等)。 - Access-Control-Allow-Headers:允许的请求头。
- Access-Control-Max-Age:预检请求的缓存时间,单位为秒。
4. OPTIONS
请求的工作流程
- 浏览器发送
OPTIONS
请求,询问服务器是否允许该跨域请求。 - 服务器返回允许的跨域设置,包括允许的请求方法、头部等。
- 如果服务器返回允许的权限,浏览器才会发送实际的
POST
请求。
5. 避免预检请求的方法
在某些情况下,可以通过以下方式避免预检请求:
- 限制请求头:避免使用自定义请求头,使用符合
CORS
简单请求标准的头部。 - 使用简单数据类型:将
POST
数据的Content-Type
设置为application/x-www-form-urlencoded
或其他简单类型。 - 使用同源策略:在客户端和服务器保持同源,避免跨域请求。
总结
POST
请求会触发 OPTIONS
预检请求是因为浏览器的 CORS 安全策略。预检请求用于检查服务器是否允许跨域访问,以确保数据安全。
6. 301, 302, 303, 307 重定向的区别
HTTP 协议中提供了多个重定向状态码(301、302、303 和 307),虽然它们的功能都是将客户端重定向到新的 URL,但使用的场景和具体含义有所不同:
1. 301 Moved Permanently(永久重定向)
- 含义:资源已永久移动到新的 URL,原始 URL 不再有效。
- 搜索引擎处理:会将旧 URL 的搜索权重转移到新的 URL 上,因此适用于资源永久变更。
- 请求方法:通常,客户端会将重定向请求的方法(如
POST
)自动更改为GET
,除非明确要求保留方法。 - 用途:适用于 URL 结构调整、永久迁移或更改域名等。
2. 302 Found(临时重定向)
- 含义:资源临时移动到新的 URL,原始 URL 仍然有效。
- 搜索引擎处理:不会转移旧 URL 的搜索权重,仅暂时指向新 URL。
- 请求方法:最初在 HTTP/1.0 中设计为保持原请求方法,但由于历史原因,许多客户端将请求方法更改为
GET
。 - 用途:适用于资源临时搬迁,例如页面维护、A/B 测试。
3. 303 See Other(查看其他位置)
- 含义:告知客户端应使用
GET
方法访问新的 URL。 - 请求方法:无论原请求方法是什么(如
POST
),客户端都应使用GET
访问新的 URL。 - 用途:常用于
POST
请求后重定向到一个显示结果的页面。例如,表单提交成功后重定向到“成功”页面。
4. 307 Temporary Redirect(临时重定向,保留方法)
- 含义:资源临时移动到新的 URL,与 302 类似,但要求客户端必须保持原请求方法。
- 请求方法:明确要求保持原请求方法,例如
POST
请求重定向后仍使用POST
。 - 用途:适用于不想改变请求方法的临时重定向,确保重定向后的请求方式一致。
区别总结
状态码 | 重定向类型 | 请求方法 | 应用场景 |
---|---|---|---|
301 | 永久 | 改为 GET | 永久迁移、URL 结构更改 |
302 | 临时 | 改为 GET | 临时重定向、页面维护 |
303 | 临时 | 强制为 GET | 表单提交后查看结果页面 |
307 | 临时 | 保持原方法 | 临时重定向,需保持请求方法 |
总结:301 是永久性重定向,302 和 307 都是临时性重定向(但 307 保持原方法),而 303 强制使用 GET
请求。302 和 301 是 HTTP 1.0 中的内容,而 303、307 等则是 HTTP 1.1 中引入的。
7. HTTP 的 Keep-Alive 是什么?
Keep-Alive 是 HTTP 协议中的一个机制,用于在同一个 TCP 连接上复用多个请求和响应。它通过保持连接不立即关闭,提升网络传输效率,减少延迟和资源消耗。
1. Keep-Alive 的作用
- 复用连接:在启用 Keep-Alive 后,客户端和服务器可以在同一条 TCP 连接上连续发送多个请求,而不是为每个请求建立新的连接。
- 减少延迟:避免了频繁建立和断开 TCP 连接的过程(TCP 握手和挥手),从而减少了延迟,提高了请求响应速度。
- 降低资源消耗:保持长连接能够减少 CPU 和内存的消耗,因为 TCP 连接的建立和释放较耗资源。
- 支持 HTTP 管道化:HTTP 管道化是允许客户端在同一 TCP 连接中连续发送多个请求而无需等待每个请求的响应的技术。当与 keep-alive 结合使用时,可以进一步提高性能。
(HTTP管道化是HTTP1.x加入的)
2. Keep-Alive 的工作原理
- Connection: Keep-Alive:客户端在请求头中加入此标识来请求保持连接。
- 服务器响应 Keep-Alive:服务器在响应头中也加上
Connection: Keep-Alive
表示支持复用连接。 - 连接时长控制:Keep-Alive 的连接并不是永久保持,服务器可以设置
Keep-Alive
的超时时间和最大请求数,例如:- Timeout:服务器允许的空闲连接时间,超过此时间无请求则关闭连接。
- Max:连接的最大请求数,到达上限后关闭连接。
3. Keep-Alive 的优缺点
- 优点:
- 提高性能:多次请求复用连接,减少延迟,提升响应速度。
- 降低开销:减少 TCP 连接的反复建立和释放,降低 CPU 和内存资源的消耗。
- 缺点:
- 服务器资源占用:如果连接保持时间过长或请求量过大,可能会占用服务器资源,影响并发性能。
- 资源管理复杂:服务器需管理并发连接,控制超时时间和最大请求数,避免资源被占用过久。
4. HTTP/2 中的 Keep-Alive
HTTP/2 引入了多路复用,可以在单个连接上传输多个流,无需依赖 Keep-Alive。这种特性使得 HTTP/2 自然支持高效的长连接传输,优化了请求并发能力。
总结
HTTP 的 Keep-Alive 机制通过复用连接,减少网络延迟和资源消耗,提升请求效率。不过,需要合理设置连接的超时和最大请求数,以避免服务器资源的过度占用。
8. 谈谈浏览器缓存和 HTTP 缓存
HTTP 和浏览器的缓存机制用于在客户端缓存资源,以减少服务器请求、加快加载速度和节省带宽。以下是 HTTP 和浏览器缓存的工作方式、常用策略和缓存控制方法。
1. 缓存的作用
- 减少网络请求:缓存减少了服务器的请求次数,提高了性能。
- 降低延迟:从本地缓存中加载资源比重新从服务器下载更快。
- 节省带宽:缓存减少了重复请求的大小和频率,节省了网络资源。
2. 缓存的类型
- 强缓存(强制缓存):在有效期内无需请求服务器,直接从缓存中读取资源。
- 协商缓存:在缓存资源过期时,请求服务器确认资源是否有更新,决定是否从缓存加载。
3. HTTP 缓存控制头
缓存控制依赖 HTTP 头部字段设置,有以下几种常见的控制头:
强缓存控制头
- Expires:使用日期时间的方式(如
Expires: Wed, 21 Oct 2025 07:28:00 GMT
)表示资源的到期时间。在到期前,资源直接从缓存中加载,但由于受限于服务器和客户端的时间同步问题,Expires 的精度较低。 - Cache-Control:用来精确设置缓存的控制策略,常见取值:
no-cache
:强制每次请求都要进行协商缓存验证。no-store
:不缓存任何内容。max-age=<seconds>
:指定资源的缓存有效期(单位秒)。在有效期内,浏览器使用缓存资源而不向服务器发送请求。public
:资源可被浏览器和代理服务器缓存。private
:资源仅浏览器可缓存,代理不可缓存。
协商缓存控制头
- Last-Modified / If-Modified-Since:服务器返回资源的最后修改时间
Last-Modified
。客户端缓存资源到期后,带If-Modified-Since
头发起请求,服务器比较资源的最后修改时间是否一致,以决定返回304 Not Modified
(未修改)或新资源。 - ETag / If-None-Match:服务器生成资源唯一标识
ETag
。客户端缓存到期后,用If-None-Match
发送 ETag 值,服务器验证该值是否一致,返回304
或新资源。相比Last-Modified
,ETag 更精确。
4. 缓存的工作流程
强缓存流程
- 浏览器检查资源是否在缓存中,且未过期。
- 若未过期,则直接从缓存读取,无需请求服务器。
- 若过期,则转为协商缓存流程。
协商缓存流程
- 浏览器向服务器发送请求,并带上
If-Modified-Since
或If-None-Match
头。 - 服务器根据资源的更新时间或 ETag 验证请求。
- 若资源无变更,服务器返回
304 Not Modified
,客户端从缓存读取。 - 若资源有变更,服务器返回新内容,更新缓存。
5. 浏览器缓存位置
- Service Worker 缓存:Service Worker 允许开发者通过编程控制资源缓存,常用于 PWA。
- Memory Cache:存储在内存中的缓存,生命周期较短,通常用于快速加载同一页面的资源。
- Disk Cache:存储在硬盘上的缓存,生命周期长,适合大文件和长期资源。
- Push Cache:HTTP/2 中的临时缓存,仅在会话期间有效,用于推送资源。
6. HTTP 缓存的常见策略
- 优先使用强缓存:如
Cache-Control: max-age=3600
,缓存 1 小时。 - 结合协商缓存:在
Cache-Control
到期后,通过ETag
或Last-Modified
进行资源验证。 - 适合静态资源:对于 JS、CSS 和图片等静态资源,可以设置较长的强缓存有效期,并通过资源文件名(如添加 hash 值)来实现缓存更新。
- 动态资源短时缓存:对频繁更新的资源可以设置较短的缓存时间,以便及时更新。
总结
HTTP 和浏览器缓存机制通过强缓存和协商缓存减少了重复请求,提升了加载速度。合理的缓存策略配置可提高网站性能,改善用户体验。开发者可以通过 Cache-Control
、ETag
等头部字段精确控制缓存行为。
9. 跨域产生的原因以及解决方案
跨域问题是指在浏览器中,当一个网页试图访问另一个域名下的资源时,由于浏览器的同源策略(Same-Origin Policy
)限制,可能会导致请求失败。跨域问题通常出现在以下场景中:
- 不同域:域名不同
- 不同协议:HTTP 与 HTTPS 不同
- 不同端口:端口号不同
为了解决跨域问题,开发者可以采用多种方法。以下是常见的跨域解决方案。
1. CORS(跨域资源共享)
CORS 是一种 W3C 标准,它允许服务器声明哪些源可以访问资源,从而控制跨域访问。通过设置 HTTP 响应头,服务器告知浏览器是否允许跨域请求。
主要头部:
- Access-Control-Allow-Origin:指定允许跨域的源。可以设置为特定域名(如
https://example.com
),或者设置为*
以允许所有域名。 - Access-Control-Allow-Methods:指定允许的 HTTP 方法,如
GET
,POST
,PUT
,DELETE
等。 - Access-Control-Allow-Headers:指定允许的请求头字段,常用于复杂请求。
- Access-Control-Allow-Credentials:是否允许发送 Cookie 信息。设置为
true
时,浏览器会携带cookies
。
优点:
- 安全可靠,符合标准。
- 可以细粒度控制跨域的权限。
缺点:
- 需要后端配合配置 CORS 响应头。
- 只能应用于现代浏览器。
使用场景:
- API 请求,允许从不同的源访问 RESTful API 或其他资源。
2. JSONP(JSON with Padding)
JSONP 是一种通过 <script>
标签进行跨域请求的技巧。浏览器允许跨域加载 <script>
标签,所以利用这一点,可以将数据请求通过 <script>
标签传递回来。JSONP 主要支持 GET 请求。
工作原理:
- 客户端在网页中创建一个
<script>
标签,URL 中携带请求参数。 - 服务器返回一段 JavaScript 代码,并在代码中执行回调函数,传递数据。
- 浏览器执行回调函数,获取数据。
优点:
- 适用于 GET 请求。
- 不依赖于 CORS 机制,兼容旧版本浏览器。
缺点:
- 仅支持 GET 请求,不能进行 POST 请求。
- 安全性较低,容易受到 XSS 攻击。
使用场景:
- 早期的跨域问题解决方案,适用于简单的 API 请求,特别是在 JSONP 支持的情况下。
function jsonp(url, jsonpCallback, success) {
let script = document.createElement("script");
script.src = url;
script.async = true;
script.type = "text/javascript";
window[jsonpCallback] = function (data) {
success && success(data);
};
document.body.appendChild(script);
}
jsonp("http://xxx", "callback", function (value) {
console.log(value);
});
3. 代理服务器
通过在同域下创建一个代理服务器,前端请求先发送到同域的代理服务器,再由代理服务器转发到目标跨域服务器,最后将响应返回给前端。
工作原理:
- 前端向同域的代理服务器发送请求。
- 代理服务器向跨域的目标服务器发送请求。
- 代理服务器将目标服务器的响应返回给前端。
优点:
- 适用于所有 HTTP 请求方法(如 GET, POST)。
- 无需修改目标服务器的 CORS 配置,所有请求通过服务器端转发,解决了跨域问题。
缺点:
- 需要配置一个代理服务器,增加了服务器的负担。
- 请求和响应的延迟可能较高。
使用场景:
- 开发环境中,常用 webpack 等开发工具进行代理。
- 生产环境中,后端服务器充当代理中介。
PS:
nginx代理跨域
nginx 具体的配置:
#proxy服务器
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
index index.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}
4. WebSocket
WebSocket 是一种网络通信协议,它提供了一个双向的全双工通道,允许浏览器和服务器之间进行低延迟的双向通信。WebSocket 避免了浏览器的同源策略限制,因为 WebSocket 是基于协议而不是基于域的。
优点:
- 实现双向通信,不受同源策略的限制。
- 可用于实时数据传输,如聊天、即时通知等。
缺点:
- 需要服务端和客户端都支持 WebSocket 协议。
- 对服务器的配置要求较高。
使用场景:
- 实时应用,如在线聊天、推送通知等。
5. iframe + postMessage
通过使用 <iframe>
标签,将跨域的网页嵌套到当前页面中,并通过 window.postMessage
实现跨域通信。
工作原理:
- 在当前页面嵌入一个
iframe
,该iframe
加载跨域的页面。 - 主页面和
iframe
页面通过window.postMessage
实现数据的双向传递。 - 使用
postMessage
传递的数据通过事件监听器接收,确保安全地进行跨域通信。
优点:
- 可以实现双向通信。
- 安全性较高,可以通过事件监听和验证接收到的数据。
缺点:
- 需要前后端配合,特别是需要设置正确的接收者和发送者。
- 使用较为复杂,且对
iframe
的管理和消息处理要求较高。
使用场景:
- 嵌入第三方应用时,解决跨域通信问题。
6. Server-Side Includes(SSI)和 HTML5 LocalStorage / SessionStorage
这两种方法通常不用于跨域的直接解决,但可以配合使用来解决某些场景下的跨域问题。
SSI:
- 通过服务器端包含(Server-Side Includes)技术,在服务器渲染页面时,将跨域的资源嵌入到页面中。
LocalStorage / SessionStorage:
- 利用浏览器的
localStorage
或sessionStorage
进行数据共享,虽然这些数据存储在客户端,但通过 JavaScript 在不同页面之间共享。
7. document.domain
配合Cookie
设置 document.domain
:如果两个页面属于同一个顶级域名下的不同子域名,可以通过设置 document.domain
为相同的顶级域名来实现跨域。但是,这种方式存在限制,并且可能引入其他安全风险。
8. BroadcastChannel
与 SharedWorker
BroadcastChannel
接口表示给定源的任何浏览上下文都可以订阅的命名频道。它允许同源的不同浏览器窗口、标签页、frame
或者 iframe
下的不同文档之间相互通信。消息通过 message 事件进行广播,该事件在侦听该频道的所有 BroadcastChannel
对象上触发,发送消息的对象除外。
SharedWorker
接口代表一种特定类型的 worker
,可以从几个浏览上下文中访问,例如几个窗口、iframe 或其他 worker
。它们实现一个不同于普通 worker
的接口,具有不同的全局作用域,
总结
解决方案 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
CORS | 安全、标准化、灵活控制 | 需要服务器配合 | API 跨域请求 |
JSONP | 简单、支持旧浏览器 | 只支持 GET 请求,安全性差 | 旧版浏览器或简单跨域请求 |
代理服务器 | 适用所有 HTTP 请求方法,灵活方便 | 增加服务器负担,延迟较高 | 开发中使用 webpack 配置代理,后端代理 |
WebSocket | 双向通信、不受同源策略限制 | 对服务器要求较高,使用复杂 | 实时应用(聊天、推送通知等) |
iframe + postMessage | 安全、双向通信 | 配置较复杂,需要前后端配合 | 嵌入第三方应用,跨域数据通信 |
通过根据实际需求选择合适的跨域解决方案,可以确保 Web 应用在不同环境下的正常运行,并优化性能和用户体验。
10. HTTP1.1 如何解决 HTTP 的队头阻塞问题?
什么是 HTTP 队头阻塞?
HTTP 传输是基于请求-应答
的模式进行的,报文必须是一发一收,但值得注意的是,里面的任务被放在一个任务队列中串行执行,一旦队首的请求处理太慢,就会阻塞后面请求的处理。这就是著名的 HTTP 队头阻塞问题。
并发连接
对于一个域名允许分配多个长连接,那么相当于增加了任务队列,不至于一个队伍的任务阻塞其它所有任务。在 RFC2616
规定过客户端最多并发 2
个连接,不过事实上在现在的浏览器标准中,这个上限要多很多,Chrome 中是 6
个。 但其实,即使是提高了并发连接,还是不能满足人们对性能的需求。
域名分片
一个域名不是可以并发 6 个长连接吗?那我就多分几个域名。 比如 content1.carlos.com
、content2.carlos.com
。 这样一个 carlos.com
域名下可以分出非常多的二级域名,而它们都指向同样的一台服务器,能够并发的长连接数更多了,事实上也更好地解决了队头阻塞的问题。
11. 聊聊Cookie
Cookie 是一种在客户端(浏览器)和服务器之间存储和传递小块数据的机制。它用于在不同的 HTTP 请求之间保持状态,解决 HTTP 协议本身无状态的问题。Cookie 允许服务器存储在客户端的信息,并在随后的请求中传递这些信息,从而实现用户身份识别、会话管理、个性化设置等功能。
1. Cookie 的基本概念
定义
Cookie 是由 Web 服务器 发送到 客户端(浏览器) 的小数据块,客户端会将其保存在本地,随着每次请求该服务器时,都会自动附带发送这些数据。
主要用途
- 用户身份识别:通过设置 Cookie,服务器可以在不同请求之间识别和验证用户。
- 会话管理:在用户登录后,可以使用 Cookie 存储会话信息,避免每次请求都需要重新登录。
- 个性化设置:Cookie 可以存储用户的偏好设置(如语言、主题)等。
- 跟踪与分析:通过在 Cookie 中存储用户行为数据,网站可以跟踪用户的访问和使用习惯,用于分析和广告推送。
2. Cookie 的工作原理
过程
- 服务器发送 Cookie:当用户访问网站时,服务器可能会在 HTTP 响应头中包含 Set-Cookie 字段,指示浏览器保存该 Cookie。
- 浏览器存储 Cookie:浏览器收到该 Cookie 后,会将其存储在本地,并在之后的每个请求中将 Cookie 附加到请求头中(如果符合设置的范围,如域名和路径等)。
- 服务器使用 Cookie:服务器通过解析请求中的 Cookie,获取用户的状态信息,并做出相应的处理。
3. Cookie 的属性
常见属性
- name=value:Cookie 的名称和值。
- expires:设置 Cookie 的过期时间。如果不设置,默认为会话 Cookie,在浏览器关闭时自动删除。
- max-age:Cookie 的最大存活时间(秒)。如果设置了该属性,则会覆盖
expires
属性。 - path:指定 Cookie 的有效路径。如果没有设置,默认为当前路径。只有在访问该路径下的页面时,Cookie 才会被发送。
- domain:指定 Cookie 的有效域名。如果没有设置,默认为当前域名。
- secure:如果设置该属性,Cookie 仅能通过 HTTPS 协议传输,增强安全性。
- HttpOnly:如果设置该属性,Cookie 无法通过 JavaScript 访问,只能在 HTTP 请求中发送,防止跨站脚本攻击(XSS)。
- SameSite:限制跨站请求时是否发送 Cookie。可以设置为
Strict
、Lax
或None
,以控制在跨站请求中是否携带 Cookie。SameSite
属性可以增强网站的安全性,防止跨站请求伪造攻击(CSRF)。
4. Cookie 的类型
会话 Cookie(Session Cookie)
- 作用:仅在浏览器会话期间有效,浏览器关闭时会被删除。
持久 Cookie(Persistent Cookie)
- 作用:具有过期时间,直到过期时间到达时,浏览器才会删除。
第三方 Cookie(Third-party Cookie)
- 作用:由第三方(如广告商)在用户访问某个网站时设置。它们通常用于跨站点的跟踪和分析。
5. Cookie 的安全性问题
安全隐患
跨站脚本攻击(XSS):
- 攻击者可以通过注入恶意 JavaScript 代码,窃取客户端的 Cookie 数据。为了防止 XSS 攻击,可以使用
HttpOnly
属性,将 Cookie 限制为只能通过 HTTP 请求访问。
- 攻击者可以通过注入恶意 JavaScript 代码,窃取客户端的 Cookie 数据。为了防止 XSS 攻击,可以使用
跨站请求伪造(CSRF):
- 攻击者利用用户的身份发起请求,伪造用户操作。为了防止 CSRF 攻击,可以使用
SameSite
属性来限制跨站请求时是否发送 Cookie。
- 攻击者利用用户的身份发起请求,伪造用户操作。为了防止 CSRF 攻击,可以使用
Cookie 劫持:
- 如果 Cookie 没有加密,攻击者可能通过窃取未加密的 Cookie 获取敏感信息。为了提高安全性,可以通过
secure
属性强制 Cookie 仅通过 HTTPS 发送。
- 如果 Cookie 没有加密,攻击者可能通过窃取未加密的 Cookie 获取敏感信息。为了提高安全性,可以通过
Cookie 漏洞:
- 如果没有设置合适的过期时间,Cookie 可能会在用户不再需要时仍然存在,增加被滥用的风险。
防范措施
- 使用
HttpOnly
和secure
属性来增强 Cookie 的安全性。 - 设置合理的
SameSite
属性来防止跨站请求伪造攻击。 - 使用 HTTPS 协议加密传输所有敏感数据,防止中间人攻击。
- 定期清理不再需要的 Cookie,避免长期存储敏感数据。
6. Cookie 与存储机制的比较
特性 | Cookie | LocalStorage / SessionStorage |
---|---|---|
存储大小 | 通常每个 Cookie 限制为 4 KB 左右 | 通常每个域名可存储 5-10 MB 数据 |
生命周期 | 根据设置的过期时间决定 | LocalStorage 永久存储,SessionStorage 会话期间有效 |
作用域 | 每次 HTTP 请求都会带上 Cookie | 只能在浏览器端 JavaScript 中访问,且与 HTTP 请求无关 |
传输方式 | 会随每个 HTTP 请求自动发送 | 不会自动发送,只能通过 JavaScript 访问 |
适用场景 | 用户身份验证、会话管理、跟踪分析等 | 存储较大数据、状态信息等 |
总结
- Cookie 是一种浏览器和服务器之间传递信息的机制,常用于会话管理、身份验证、个性化设置等。
- Cookie 的一些安全隐患,如 XSS、CSRF 和 Cookie 劫持,要求开发者采取防范措施(如
HttpOnly
、Secure
、SameSite
)。 - 相比于 LocalStorage 和 SessionStorage,Cookie 的存储容量较小,且每次请求都会带上,可能影响性能。但在一些需要服务器读取的场景下,Cookie 依然是必要的解决方案。
12. 如何理解 HTTP 代理?
我们知道在 HTTP 是基于请求-响应模型的协议
,一般由客户端发请求,服务器来进行响应。 当然,也有特殊情况,就是代理服务器的情况。引入代理之后,作为代理的服务器相当于一个中间人的角色,对于客户端而言,表现为服务器进行响应;而对于源服务器,表现为客户端发起请求,具有双重身份。
功能
负载均衡。客户端的请求只会先到达代理服务器,后面到底有多少源服务器,IP 都是多少,客户端是不知道的。因此,这个代理服务器可以拿到这个请求之后,可以通过特定的算法分发给不同的源服务器,让各台源服务器的负载尽量平均。当然,这样的算法有很多,包括随机算法、轮询、一致性 hash、LRU(最近最少使用)等等,不过这些算法并不是本文的重点,大家有兴趣自己可以研究一下。
保障安全。利用心跳机制监控后台的服务器,一旦发现故障机就将其踢出集群。并且对于上下行的数据进行过滤,对非法 IP 限流,这些都是代理服务器的工作。
缓存代理。将内容缓存到代理服务器,使得客户端可以直接从代理服务器获得而不用到源服务器那里。下一节详细拆解。
13.什么是重绘和回流及怎么减少重绘和回流?
重绘(Repaint) 和 回流(Reflow) 是浏览器渲染页面时涉及的两个关键过程。理解它们的区别以及如何优化这些过程,能有效提高网页的渲染性能,特别是在进行动态 DOM 操作时。
1. 重绘(Repaint)简介
1.1 定义
重绘 是指当网页的元素发生样式变化,但不影响布局时,浏览器重新绘制页面的过程。例如,元素的颜色、背景色、透明度等视觉样式发生变化时,浏览器会进行重绘。
1.2 典型场景
- 修改元素的颜色 (
background-color
,color
)。 - 改变透明度 (
opacity
)。 - 修改字体样式 (
font-family
,font-size
)。
1.3 性能影响
- 重绘通常比回流更轻量,不涉及布局计算。
- 虽然开销较小,但频繁的重绘仍然会影响性能,尤其是涉及大量 DOM 元素时。
2. 回流(Reflow)简介
2.1 定义
回流(也称为布局重排)是指当网页布局发生变化时,浏览器重新计算元素的位置、大小等几何属性,并重新绘制整个页面。回流比重绘开销更大,因为它不仅涉及重新绘制,还需要计算布局。
2.2 典型场景
- 修改元素尺寸(如
width
,height
)。 - 改变元素位置(如
top
,left
)。 - 删除或插入 DOM 元素,导致布局变化。
- 修改影响布局的属性(如
display
,position
,visibility
)。
2.3 性能影响
- 回流的开销较大,尤其是当修改 DOM 导致复杂的布局更新时。
- 在页面结构复杂时,回流可能导致性能瓶颈。
3. 重绘与回流的关系
- 重绘是回流的一部分:当回流发生时,通常会伴随重绘,因为布局变化后,浏览器需要重新绘制页面。但是重绘不一定伴随回流,即某些仅涉及视觉变化的修改(如颜色变化)不会引发回流。
- 性能开销:回流通常比重绘消耗更多的资源,因为它不仅需要计算新布局,还需要重新绘制页面。
4. 如何减少重绘和回流?
为了提高网页性能,减少重绘和回流的次数至关重要。以下是一些优化方法:
4.1 批量修改样式,避免多次操作
- 批量修改 DOM 样式:避免在多次修改时分别触发回流或重绘,尽量将多次样式修改集中在一起,减少 DOM 更新次数。
- 例如,先计算出所有需要修改的样式,再一次性应用。
4.2 避免强制同步布局
- 访问布局属性的时机:避免在修改布局后立即访问会触发回流的属性(如
offsetHeight
,offsetWidth
,clientHeight
,clientWidth
)。因为浏览器可能会强制执行回流并更新页面。
4.3 使用 requestAnimationFrame
优化动画
- 对于动画操作,使用
requestAnimationFrame
来优化渲染。它能够在浏览器的下一次重绘周期内同步进行动画更新,从而避免不必要的重绘或回流。
4.4 合理使用 CSS 动画
- 使用 CSS 动画 替代 JavaScript 动画,因为 CSS 动画通常由浏览器优化,能更有效地避免引发回流。
4.5 减少 DOM 操作
- 减少频繁的 DOM 操作:对 DOM 的频繁增删改查会触发回流。将多次 DOM 操作合并在一起,减少重排的次数。
- 例如,可以通过
DocumentFragment
来批量处理 DOM 变动,减少回流的次数。
- 例如,可以通过
4.6 使用 position: absolute
和 position: fixed
- 这两种定位方式将元素脱离文档流,避免影响其他元素布局,从而减少回流的发生。
4.7 避免表格布局
- 表格布局尤其是复杂的嵌套表格会导致浏览器频繁计算布局。应尽量使用
flexbox
或grid
布局替代表格布局,以减少回流。
4.8 合并 CSS 选择器
- 减少 CSS 选择器的数量,避免过多的选择器引发回流。
5. 总结
- 重绘(Repaint) 是页面样式变化时,浏览器重新绘制页面的操作,不涉及布局改变,性能开销相对较小。
- 回流(Reflow) 是页面布局变化时,浏览器重新计算和调整元素的大小和位置,开销较大。
- 为了提高性能,应尽量减少重绘和回流的次数,使用合适的技巧如批量修改样式、避免频繁的 DOM 操作、使用 CSS 动画等方式进行优化。
14.web 安全攻击方式及防御方法
1、SQL 注入
SQL 注入是一种常见的 Web 应用安全漏洞,攻击者通过在 Web 应用的输入参数中注入恶意的 SQL 代码,从而执行未经授权的数据库操作。这种类型的攻击允许攻击者访问,删除或修改数据库中的数据。
防御方法:使用参数化查询、输入验证和限制数据库权限等方法来防止 SQL 注入攻击。移除或转义特殊字符,如单引号等,防止恶意 SQL 代码的执行。为数据库用户分配最小必要的权限,以减少攻击者能够利用 SQL 注入漏洞对数据库进行的操作。使用 ORM(对象关系映射)框架可以减少直接操作数据库的需求,并且 ORM 通常有内置的参数化查询等安全特性。定期进行安全审计和漏洞扫描,以及对 Web 应用程序进行安全测试,确保及时发现和修复潜在的 SQL 注入漏洞。
2、跨站脚本攻击 (XSS)
是一种常见的网络安全漏洞,攻击者通过在网页上注入恶意脚本,以获取用户的敏感信息或劫持用户的会话。XSS 攻击通常分为存储型 XSS、反射型 XSS 和 DOM 型 XSS。
防御方法:对用户输入的数据进行严格的验证和过滤,移除或转义潜在的恶意脚本。在把用户输入的数据输出到网页时,进行适当的编码,以防止恶意脚本的执行。通过设置 CSP(Content Security Policy) HTTP 头部,限制网页可以加载的资源和执行的脚本,防止 XSS 攻击。选择使用经过安全审计和有良好安全记录的框架和库,以减少 XSS 攻击的风险。对敏感信息进行加密存储和传输,防止泄露。
3、跨站请求伪造 (CSRF)
攻击者利用受害者在已登录的情况下身份验证的权限,对受害者进行操作。攻击者通过伪装的请求来执行未经授权的操作,比如修改密码、发送电子邮件或进行资金转账等。
防御方法:使用 CSRF 令牌,验证 referer 头部信息,将 CSRF 令牌存储在 Cookie 中,并同时将该令牌作为参数发送给服务器。服务器将比较这两个值是否匹配,从而验证请求的合法性。在每个请求中添加一个随机或不可预测的参数,攻击者无法获得该参数的值,因此无法伪造有效请求。通过使用 CSP,可以帮助防止恶意脚本的注入和执行,从而减少 CSRF 攻击的风险。
4、未经授权的访问
可能导致未经授权的个人或实体获取敏感信息、系统功能或资源。
防御方法:加强身份认证,实施访问控制和权限管理,强化密码策略,强化操作系统和应用程序安全。定期对系统进行审计和监控,以及实时监控系统日志,以检测异常操作和未经授权的访问尝试。使用网络防火墙来限制流量,阻止未经授权的访问,并使用 IDS 来检测和响应来自未经授权用户的攻击。
5、重定向攻击
这种在一些钓鱼网站中经常见到,一般会发送给用户一个合法链接,这个链接被用户点击的时候,导向进入一个非法网站,从而达到骗取用户信任、窃取用户资料的目的。
避免攻击:一般来说我们需要审核重定向的网址,通过加入黑白名单的方式监控。
6、文件上传漏洞
恶意用户通过应用程序的文件上传功能,将恶意文件(如病毒、木马、恶意脚本等)上传到服务器上,从而导致网站安全漏洞和潜在的安全威胁。
防御方法:严格限制上传文件类型和大小,对上传的文件进行合理的检查和过滤,设定合理的文件权限。在服务器端对上传的文件进行扩展名检查,以确保上传的文件扩展名与其真实类型一致,防止对文件伪装的攻击。使用安全的文件内容检测工具,对上传的文件进行扫描和检测,以确保文件不包含恶意代码。如果发现恶意代码,立即将文件视为不安全并予以阻止或删除。
7、目录遍历攻击
通过输入恶意构造的文件路径来获取未经授权的文件或目录访问权限。
防御方法:限制用户访问权限,严格控制访问文件路径,过滤用户输入的目录遍历字符。对 URL 进行编码处理,以防止用户输入中包含恶意路径分隔符,从而避免目录遍历攻击。确保关闭不必要的文件和目录访问权限,避免出现目录遍历漏洞。
8、代码执行漏洞
应用程序在处理输入时未正确进行过滤和验证,导致恶意用户能够向应用程序提交恶意代码,从而在服务器上执行任**意指令。这种漏洞很容易被黑客利用,造成严重的安全风险。 **防御方法:将应用程序运行在沙盒环境中,对用户输入进行严格过滤和验证,限制用户的执行权限,定期对代码进行安全审计。
9、点击劫持攻击
攻击者创建一个透明的图层,并在上面放置一个看似吸引人的元素,例如按钮、链接或表单,然后诱使用户在不知情的情况下点击这个看似无害的元素,实际上用户的点击被重定向到攻击者想要的网页或执行特定的操作。点击劫持攻击可能导致用户执行意外的操作,例如在未经许可的情况下购买商品或泄露个人敏感信息。
防御方法:使用 X-Frame-Options 头部,限制网页被嵌套,并提示用户外部引用。在网页上增加一层透明的 DIV,并检查用户点击的位置是否在预期范围内。在编写网页时,需要对用户的操作做合适的限制和验证,确保用户的点击不会被误导到其他页面或执行危险的操作。
10、cookie 攻击
主要是利用 JavaScript 能够在当前域名下获取网站 cookie 的特性来攻击(javascript:alert(doucment.cookie)),一般来说可以配合 XSS 和 CSRF 来进行攻击,
避免攻击:现在主流浏览器都支持在 cookie 上加上 HttpOnly 的属性,这样 cookie 就无法通过 Java Script 来取得,如果能在关键 cookie 上打上这个标记,对 cookie 的安全性的提高有很大作用。
11、DOS 攻击
拒绝服务攻击(denial-of-service attack, DoS)亦称洪水攻击,这也是网络安全领域不得不提到的一个攻击,主要攻击方式为不断的向目标服务器进行强烈多次的攻击,这种攻击及其消耗服务器的带宽和资源,最终使得服务器资源耗尽而崩塌。
避免攻击:这种攻击一般可以通过一些防火墙策略和报警机制来解决,同时配上人为监控。简单的讲可以对访问过多的 IP 进行封禁。深入一点讲,可以做一些流量清洗方案。采用抗 DDoS 软件,将正常流量和恶意流量区分开。
15. TCP 和 UDP 的区别
TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protocol,用户数据报协议)都是传输层协议,负责在计算机网络中进行数据的传输。它们有着不同的特性和应用场景。
1. 基本定义
1.1 TCP(传输控制协议)
TCP 是一种面向连接的、可靠的传输协议。它在数据传输之前需要进行连接的建立,并确保数据的可靠到达。
1.2 UDP(用户数据报协议)
UDP 是一种无连接的、不可靠的传输协议。它不保证数据的顺序和可靠性,数据可能丢失、重复或者乱序到达。
2. 主要区别
特性 | TCP | UDP |
---|---|---|
连接类型 | 面向连接(需要建立连接) | 无连接(不需要建立连接) |
可靠性 | 高度可靠(数据保证到达,按顺序) | 不可靠(数据可能丢失、乱序) |
传输方式 | 字节流传输 | 数据报文传输 |
拥塞控制 | 有拥塞控制机制 | 没有拥塞控制 |
流量控制 | 有流量控制机制 | 没有流量控制 |
传输速度 | 较慢(需要确认和重传机制) | 较快(无连接,少有控制) |
首部开销 | 较大(20 字节) | 较小(8 字节) |
可靠交付 | 保证数据可靠传输(通过重传、确认等机制) | 不保证数据可靠传输 |
顺序保证 | 保证数据按顺序到达 | 不保证数据顺序 |
适用场景 | 适用于需要高可靠性的应用(如 HTTP、FTP 等) | 适用于对速度要求高、可容忍丢失数据的应用(如实时视频、DNS 查询等) |
3. 连接管理
3.1 TCP 连接管理
TCP 使用三次握手(三-way handshake)建立连接,并使用四次挥手(four-way handshake)断开连接,确保双方都能够正确地建立和断开连接。
3.2 UDP 连接管理
UDP 不需要建立连接。数据直接以数据包的形式发送给目标地址,目标地址不需要回应确认。
4. 应用场景
4.1 TCP 适用场景
- HTTP/HTTPS:Web 浏览、网页加载需要可靠性。
- FTP:文件传输需要数据的顺序和完整性。
- SMTP/POP3/IMAP:电子邮件传输要求数据的可靠性。
4.2 UDP 适用场景
- 视频流和音频流:实时性要求较高,丢失一些数据包不会影响整体体验(如视频通话、直播)。
- DNS:简单的查询请求,快速响应。
- VoIP:语音通信对实时性要求高,可以容忍部分数据包丢失。
5. 总结
- TCP 提供可靠的、顺序化的传输,适用于对数据可靠性有较高要求的应用场景。
- UDP 提供快速的、无连接的传输,适用于实时性要求高、对数据丢失能够容忍的场景。
16. TCP 的三次握手与四次挥手
TCP 是一种面向连接的可靠协议,在建立连接和断开连接时会进行一系列的操作,确保数据的可靠传输。三次握手用于建立连接,四次挥手用于断开连接。
1. 三次握手过程(建立连接)
三次握手是建立 TCP 连接的过程,在双方通信之前,必须确保彼此能够正常通信。其过程如下:
1.1 第一次握手(SYN)
- 客户端发送一个 SYN(同步序列号) 标志位的数据包到服务器,请求建立连接。
- 包含客户端的初始序列号(seq=x)。
1.2 第二次握手(SYN-ACK)
- 服务器收到客户端的 SYN 包后,确认接收到并准备建立连接,向客户端发送一个 SYN-ACK(同步-确认) 数据包。
- 服务器生成一个初始序列号(seq=y),并在确认号(ack)中包含客户端的序列号 + 1(ack=x+1)。
1.3 第三次握手(ACK)
- 客户端收到服务器的 SYN-ACK 包后,向服务器发送一个 ACK(确认) 包,确认连接建立。
- 客户端的确认号(ack)为服务器的序列号 + 1(ack=y+1)。
此时,双方的连接成功建立,数据可以开始传输。
2. 四次挥手过程(断开连接)
四次挥手是断开 TCP 连接的过程,确保双方都能正常终止连接。其过程如下:
2.1 第一次挥手(FIN)
- 客户端发送一个 FIN(结束) 标志位的数据包,表示客户端没有数据要发送了,准备断开连接。
- 包含客户端的序列号(seq=u)。
2.2 第二次挥手(ACK)
- 服务器收到客户端的 FIN 包后,发送一个 ACK(确认) 数据包,确认接收到客户端的断开连接请求。
- 服务器的确认号(ack)为客户端的序列号 + 1(ack=u+1)。
2.3 第三次挥手(FIN)
- 服务器准备关闭连接时,发送一个 FIN 包到客户端,表示服务器端的数据也已经发送完毕,准备关闭连接。
- 包含服务器的序列号(seq=v)。
2.4 第四次挥手(ACK)
- 客户端收到服务器的 FIN 包后,发送一个 ACK 包进行确认,表示客户端已收到服务器的断开连接请求。
- 客户端的确认号(ack)为服务器的序列号 + 1(ack=v+1)。
此时,连接完全断开,双方可以释放资源。
3. 总结
- 三次握手:确保双方都能够正常接收对方的连接请求,建立可靠的连接。
如果只使用两次握手,客户端发送 SYN 包后,服务器响应 SYN-ACK,接着就认为连接建立了。然而,假如服务器响应后客户端没有收到(如丢包或延迟),客户端并不会知道服务器是否成功收到请求,这就会导致不可靠的连接。
- 四次挥手:确保双方都能够正常关闭连接,确保数据的完整传输,避免资源泄漏。
如果只三次挥手无法保证在关闭连接时,双方的数据能够被完整地传输和确认。如果客户端和服务器没有各自独立的关闭过程,可能会导致在连接断开时,未发送完的数据丢失
17. TCP/IP 协议模型
TCP/IP 协议模型包含四个层次,分别处理不同的网络通信功能:
1. 应用层(Application Layer)
- 功能:应用层直接与用户的应用程序交互,提供数据通信服务。
- 协议:
- HTTP/HTTPS:网页浏览协议。
- FTP:文件传输协议。
- SMTP:邮件发送协议。
- DNS:域名解析协议。
2. 传输层(Transport Layer)
- 功能:传输层负责端到端的通信,确保数据的可靠传输、顺序传递和错误控制。
- 协议:
- TCP:面向连接的可靠协议,确保数据顺序和完整性。
- UDP:无连接的、不可靠的协议,适用于实时应用。
3. 网络层(Network Layer)
- 功能:网络层负责将数据从源主机传输到目标主机,涉及路由、寻址和数据包转发。
- 协议:
- IP:互联网协议,负责数据包的路由和转发。
- ICMP:用于发送错误消息和操作信息。
- ARP:地址解析协议,用于将 IP 地址映射到 MAC 地址。
4. 数据链路层(Data Link Layer)
- 功能:数据链路层负责在物理媒介上进行数据的可靠传输,进行数据的封装与解封装。
- 协议:
- Ethernet:局域网协议。
- PPP:点对点协议。
- Wi-Fi:无线网络协议。
总结:
- 应用层:处理应用程序与网络通信之间的交互。
- 传输层:提供端到端的通信,确保数据的可靠传输。
- 网络层:负责数据包路由和传输。
- 数据链路层:确保数据在物理网络上的可靠传输。
每一层都依赖于上一层的服务来完成任务。
18. HTTP 请求方法及适用场景
1. GET
- 功能:请求指定的资源。它是最常用的 HTTP 方法,主要用于从服务器获取数据。
- 特点:
- 无副作用:GET 请求通常用于获取数据,不应有任何副作用(如更改数据)。
- 安全性:不会改变服务器状态。
- 幂等性:多次发送相同的 GET 请求,服务器的状态不会改变,结果也应该是一样的。
- 使用场景:
- 获取网页内容。
- 获取图片、视频等静态资源。
- 获取 API 数据(如查询列表)。
2. POST
- 功能:向指定资源提交数据,用于提交表单、上传文件等操作,通常用于创建或更新资源。
- 特点:
- 有副作用:POST 请求可能会导致服务器状态改变。
- 非幂等性:多次提交 POST 请求可能会导致数据重复或状态变化。
- 使用场景:
- 提交表单数据(如注册、登录等)。
- 上传文件。
- 创建新资源(如创建新文章、用户等)。
- 调用 API 进行数据处理。
3. PUT
- 功能:向指定资源上传数据,通常用于更新资源的内容。如果资源不存在,PUT 请求通常会创建该资源。
- 特点:
- 幂等性:PUT 请求是幂等的,发送多次请求后,结果应该是相同的。
- 替代资源:PUT 请求会替换指定资源的全部内容。
- 使用场景:
- 更新已存在的资源,如修改用户信息、修改文章内容等。
- 创建资源(若资源不存在时)。
4. DELETE
- 功能:删除指定的资源。
- 特点:
- 幂等性:DELETE 请求通常是幂等的,即删除资源的操作不论执行多少次,效果都是相同的(资源被删除)。
- 使用场景:
- 删除数据(如删除某篇文章、用户等)。
- 删除文件或记录。
5. PATCH
- 功能:用于更新资源的部分内容。与 PUT 不同,PATCH 请求仅更新资源的部分数据,而不是替换整个资源。
- 特点:
- 非幂等性(一般情况下),但具体情况取决于实现。
- 部分更新:只修改资源的一部分字段或数据。
- 使用场景:
- 修改资源的部分内容,如更新用户的某个字段、编辑文章的某一部分等。
6. OPTIONS
- 功能:请求服务器支持哪些 HTTP 方法,用于查看服务器的请求选项。
- 特点:
- 无副作用:OPTIONS 请求不会对服务器状态造成影响。
- 响应头:服务器返回的响应头中包含允许的 HTTP 方法(如 GET、POST、PUT、DELETE 等)。
- 使用场景:
- 检查服务器支持哪些 HTTP 方法。
- CORS(跨域资源共享)时,浏览器会首先发送 OPTIONS 请求来检测服务器是否允许跨域访问。
7. HEAD
- 功能:与 GET 请求类似,但是服务器只返回响应头,不返回响应体。用于获取资源的元信息(如文件大小、类型等)。
- 特点:
- 无副作用:仅请求头部,不请求实际内容。
- 幂等性:HEAD 请求是幂等的。
- 使用场景:
- 获取资源的元数据(如文件大小、修改日期等)。
- 检查文件是否存在或修改日期,且不下载资源本身。
8. TRACE
- 功能:回显服务器收到的请求,用于调试和诊断。服务器返回收到的请求内容,通常用于跟踪请求的路由。
- 特点:
- 用于调试:通常用于排查网络问题。
- 不常用:现代 Web 应用中不常用。
- 使用场景:
- 调试 HTTP 请求的传递路径,帮助开发人员识别问题。
总结
方法 | 描述 | 典型使用场景 |
---|---|---|
GET | 请求资源 | 获取页面、数据查询等 |
POST | 提交数据 | 提交表单、上传文件、创建资源 |
PUT | 替换资源 | 更新资源(如修改数据) |
DELETE | 删除资源 | 删除资源或数据(如删除记录) |
PATCH | 部分更新资源 | 修改资源的部分内容 |
OPTIONS | 查看服务器支持的 HTTP 方法 | 检查 CORS 或查询支持的 HTTP 方法 |
HEAD | 获取响应头部信息 | 获取资源的元数据 |
TRACE | 回显请求,调试诊断用 | 调试 HTTP 请求的传输路径 |
19. HTTP 与 HTTPS 的区别
1. 定义
- HTTP:是一种无加密的协议,用于在客户端和服务器之间传输数据。
- HTTPS:是 HTTP 的安全版本,它通过 SSL/TLS 协议对数据进行加密,确保数据的安全传输。
2. 安全性
- HTTP:数据传输过程中没有加密,数据在传输过程中是明文的,容易受到中间人攻击、窃听和篡改。
- HTTPS:使用 SSL/TLS 协议对数据进行加密,确保数据在传输过程中不会被窃取或篡改,提供数据的机密性和完整性。
3. 端口
- HTTP:默认使用 80 端口。
- HTTPS:默认使用 443 端口。
4. 加密方式
- HTTP:不提供加密功能,数据以明文形式传输。
- HTTPS:使用 SSL/TLS 加密协议,数据在传输前会被加密,确保传输过程中的数据安全。
5. 性能
- HTTP:由于没有加密和解密的过程,性能较好,数据传输速度较快。
- HTTPS:由于需要加密和解密数据,性能略低,可能会影响数据传输的速度,但随着硬件和优化的提高,这种差距已经逐渐减少。
6. URL 格式
- HTTP:URL 以
http://
开头。 - HTTPS:URL 以
https://
开头。
7. 浏览器提示
- HTTP:浏览器不会显示任何特殊提示。
- HTTPS:浏览器会在地址栏显示一个 锁形图标 或者显示 “安全” 提示,表示连接是加密的。
8. 证书
- HTTP:没有证书的需求。
- HTTPS:需要使用 SSL/TLS 证书来加密连接。服务器必须获取并安装有效的证书,以确保与客户端的连接是安全的。
9. 使用场景
- HTTP:
- 用于不涉及敏感数据交换的场景,例如博客、新闻网站、公共页面等。
- HTTPS:
- 用于涉及敏感数据的场景,例如网上银行、购物网站、登录页面等,确保用户数据(如用户名、密码、信用卡信息)不被泄露。
10. 中间人攻击
- HTTP:容易受到中间人攻击(MITM),攻击者可以拦截并篡改传输的数据。
- HTTPS:通过加密传输,有效防止中间人攻击,确保数据的机密性和完整性。
总结
特性 | HTTP | HTTPS |
---|---|---|
加密 | 不加密 | 使用 SSL/TLS 加密 |
端口 | 80 | 443 |
性能 | 较快 | 稍慢(因加密解密过程) |
安全性 | 不安全 | 安全(防止窃听、篡改) |
证书 | 不需要证书 | 需要 SSL/TLS 证书 |
使用场景 | 公共网页、非敏感数据 | 需要保护敏感数据的场景 |
20. HTTP 协议有哪些特点
1. 无状态(Stateless)
- 定义:每个 HTTP 请求都是独立的,服务器不会记住任何先前的请求信息。
- 影响:每个请求都需要包含完整的信息,如身份验证等。为了保持状态,通常会使用 Cookie 或 Session。
2. 无连接(Connectionless)
- 定义:HTTP 协议在传输数据时,每个请求和响应都在独立的连接上进行,一旦请求和响应完成,连接就会被关闭。
- 影响:每次请求都需要重新建立连接,这可能导致一些性能问题,但通过 HTTP Keep-Alive 可以保持连接在多个请求间复用,从而减少建立连接的开销。
3. 客户端-服务器模式(Client-Server Model)
- 定义:HTTP 基于客户端-服务器模式,客户端发起请求,服务器响应请求。
- 影响:客户端和服务器在功能上是分离的,客户端不需要知道服务器的内部工作,服务器只需处理请求并返回响应。
4. 基于请求/响应模式(Request-Response Model)
- 定义:HTTP 是基于请求和响应的交互模式。客户端通过发送 HTTP 请求向服务器请求资源,服务器根据请求返回响应。
- 影响:这种模式简单直观,适用于大多数 Web 应用。
5. 支持灵活的请求方法(Methods)
- 定义:HTTP 协议支持多种请求方法来执行不同的操作。常见的方法有:
- GET:请求资源,通常用于获取数据。
- POST:提交数据,通常用于创建资源或发送数据到服务器。
- PUT:更新资源,通常用于替换指定资源。
- DELETE:删除资源,通常用于删除指定资源。
- HEAD:获取响应头,类似 GET,但不返回具体内容。
- OPTIONS:查询服务器支持的请求方法。
- PATCH:部分更新资源。
6. 支持多种数据格式(MIME Types)
- 定义:HTTP 支持多种不同的数据格式,如 HTML、JSON、XML、JPEG、PNG 等。通过请求和响应头中的
Content-Type
字段,客户端和服务器可以指明发送和接收的内容类型。 - 影响:这种灵活性使得 HTTP 能够支持多种类型的资源传输。
7. 可扩展性(Extensibility)
- 定义:HTTP 协议通过头部字段(Header)支持扩展。例如,服务器可以通过添加自定义的头部来提供额外的功能(如 X-Frame-Options、Authorization 等)。
- 影响:HTTP 的可扩展性使得它能够适应不同的需求,支持新的功能和协议。
8. 支持缓存机制(Caching)
- 定义:HTTP 协议支持缓存机制,通过
Cache-Control
、Expires
、ETag
等头部来缓存响应数据,减少服务器负载并提高客户端的性能。 - 影响:缓存机制使得频繁请求的资源能够从本地缓存中获取,从而提高访问速度和减少带宽消耗。
9. 基于文本的协议(Text-Based)
- 定义:HTTP 是一个基于文本的协议,消息体由纯文本表示,包含请求方法、头部字段和响应内容等。
- 影响:这种设计使得 HTTP 协议容易理解和调试。使用文本格式的请求和响应也有助于跨平台的兼容性。
10. 明文传输(Insecure)
- 定义:传统的 HTTP 协议不对数据进行加密,所有数据都是以明文形式传输。
- 影响:这种设计可能导致数据在传输过程中被窃听或篡改,因此 HTTPS(HTTP Secure)协议通过 SSL/TLS 提供加密和安全性,解决了这一问题。
11. 支持持久连接(HTTP Keep-Alive)
- 定义:HTTP/1.1 引入了持久连接(Keep-Alive),允许在一个 TCP 连接中进行多个请求和响应,减少了连接的建立和断开的开销。
- 影响:提高了 HTTP 的性能,尤其是在进行多个请求的情况下。
12. 支持管道化(Pipelining)
- 定义:HTTP/1.1 支持管道化技术,允许在等待一个请求的响应时,发送多个请求。
- 影响:这种技术提高了网络效率,减少了等待时间。但它在实际应用中被 HTTP/2 的多路复用所替代。
总结
特性 | 说明 |
---|---|
无状态 | 每个请求是独立的,服务器不会保存状态信息 |
无连接 | 每个请求和响应都是独立的,完成后关闭连接 |
请求/响应模式 | 客户端请求资源,服务器响应请求 |
方法支持 | 支持多种 HTTP 方法,如 GET、POST、PUT、DELETE 等 |
数据格式支持 | 支持多种数据格式,如 HTML、JSON、XML、图片等 |
可扩展性 | 支持通过头部扩展功能,满足不同需求 |
缓存机制 | 支持缓存,优化性能并减少服务器负载 |
文本协议 | 基于文本的协议,容易调试和理解 |
明文传输 | 数据以明文传输,缺乏安全性,建议使用 HTTPS |
持久连接 | HTTP/1.1 引入了持久连接机制,减少了连接开销 |
管道化 | HTTP/1.1 支持管道化,可以在一个连接中发起多个请求 |
HTTP 协议的这些特点使其成为 Web 通信的基础,但在一些场景下,由于性能和安全的限制,通常会使用 HTTPS 等安全的扩展协议。
21. 请求头和响应头都有什么常见的属性
一、请求头(Request Headers)
请求头是客户端发送给服务器的部分,用于提供客户端的环境信息、请求参数以及额外的请求控制信息。
1. Accept
- 定义:指定客户端能够处理的响应内容类型(MIME 类型)。
- 示例:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
- 作用:帮助服务器决定返回哪种类型的内容。
2. Accept-Encoding
- 定义:指定客户端支持的内容编码(如压缩方式)。
- 示例:
Accept-Encoding: gzip, deflate, br
- 作用:服务器可以根据此头部选择合适的压缩算法来压缩响应体。
3. Authorization
- 定义:包含用于认证的凭据,通常用于发送用户名和密码(如 Basic Auth 或 Bearer Token)。
- 示例:
Authorization: Bearer <token>
- 作用:用于客户端向服务器提供身份验证信息。
4. User-Agent
- 定义:包含发出请求的客户端应用程序的信息(通常是浏览器或其他 HTTP 客户端)。
- 示例:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
- 作用:服务器可以根据此信息来判断客户端的类型,以便提供更合适的响应。
5. Host
- 定义:指定请求的目标主机(域名)和端口号。
- 示例:
Host: www.example.com
- 作用:在 HTTP/1.1 中必需,特别是在多个网站共享一个 IP 地址时,服务器根据此头部判断访问哪个虚拟主机。
6. Cookie
- 定义:包含客户端存储的所有 cookie 数据。
- 示例:
Cookie: sessionId=abc123; userId=12345
- 作用:服务器使用该信息来识别客户端的会话状态、用户标识等。
7. Referer
- 定义:指示请求来自哪个页面,即上一个访问的 URL。
- 示例:
Referer: https://www.example.com/previous-page
- 作用:可用于分析来源、提供链接追踪等。
8. Accept-Language
- 定义:指定客户端能够接受的语言类型。
- 示例:
Accept-Language: en-US,en;q=0.5
- 作用:根据此头部,服务器可以返回客户端首选的语言版本。
9. Connection
- 定义:指定当前连接的选项,通常用于控制是否保持持久连接。
- 示例:
Connection: keep-alive
- 作用:告知服务器是否保持当前 TCP 连接。
10. If-Modified-Since
- 定义:用于条件请求,指定自某个时间点以来,资源是否被修改过。
- 示例:
If-Modified-Since: Wed, 21 Oct 2020 07:28:00 GMT
- 作用:服务器根据资源最后修改时间判断是否返回 304 Not Modified 状态码。
二、响应头(Response Headers)
响应头是服务器发送给客户端的部分,包含了服务器处理请求后的一些信息和指示。
1. Content-Type
- 定义:指示响应体的 MIME 类型。
- 示例:
Content-Type: text/html; charset=UTF-8
- 作用:告诉客户端如何解析响应内容。
2. Content-Length
- 定义:指示响应体的大小,以字节为单位。
- 示例:
Content-Length: 1234
- 作用:告诉客户端响应体的长度,以便它知道什么时候完成接收。
3. Cache-Control
- 定义:控制缓存机制,指定资源的缓存策略。
- 示例:
Cache-Control: no-cache, no-store, must-revalidate
- 常见值:
no-cache
:要求每次请求都验证资源是否改变。no-store
:不允许缓存。max-age=seconds
:指定缓存存活的最大时长。
4. Set-Cookie
- 定义:用于在响应中设置 cookie。
- 示例:
Set-Cookie: sessionId=abc123; Path=/; Secure; HttpOnly
- 作用:设置客户端的 cookie 信息,供后续请求使用。
5. Location
- 定义:用于重定向客户端,指示新的 URL 地址。
- 示例:
Location: https://www.example.com/new-page
- 作用:通常用于 3xx 重定向状态码。
6. Server
- 定义:标识响应的服务器软件信息。
- 示例:
Server: Apache/2.4.41 (Unix)
- 作用:告知客户端服务器的类型或版本信息。
7. ETag
- 定义:资源的版本标识符,用于优化缓存。
- 示例:
ETag: "686897696a7c876b7e"
- 作用:与
If-None-Match
配合使用,允许客户端在资源未更改时跳过重新下载。
8. Last-Modified
- 定义:表示资源的最后修改时间。
- 示例:
Last-Modified: Tue, 15 Nov 2020 12:45:00 GMT
- 作用:客户端使用该信息判断资源是否已经过期。
9. Access-Control-Allow-Origin
- 定义:指示允许哪些外部域访问资源。
- 示例:
Access-Control-Allow-Origin: *
- 作用:支持跨域资源共享(CORS),允许指定域的客户端访问资源。
10. X-Content-Type-Options
- 定义:用于防止浏览器对响应的 MIME 类型进行猜测。
- 示例:
X-Content-Type-Options: nosniff
- 作用:提高安全性,防止某些类型的攻击。
11. Strict-Transport-Security (HSTS)
- 定义:要求客户端使用 HTTPS 协议访问该站点。
- 示例:
Strict-Transport-Security: max-age=31536000; includeSubDomains
- 作用:强制浏览器仅通过 HTTPS 访问,防止中间人攻击。
12. Transfer-Encoding
- 定义:指示响应体的传输编码方式。
- 示例:
Transfer-Encoding: chunked
- 作用:用于分块传输编码,允许服务器分多次传输响应体。
总结
请求头 | 说明 |
---|---|
Accept | 客户端可接受的响应内容类型 |
Authorization | 用于身份验证的凭据 |
Cookie | 客户端发送的 cookie 信息 |
User-Agent | 客户端应用程序(如浏览器)信息 |
Host | 请求的主机地址 |
Referer | 上一个访问的 URL |
If-Modified-Since | 资源是否被修改的条件请求头 |
响应头 | 说明 |
---|---|
Content-Type | 响应体的 MIME 类型 |
Set-Cookie | 设置响应中的 cookie |
Cache-Control | 控制缓存行为 |
Location | 用于重定向客户端 |
ETag | 资源的版本标识符 |
Access-Control-Allow-Origin | 允许的跨域源 |
Strict-Transport-Security | 强制使用 HTTPS 访问该站点 |
这些请求头和响应头字段在 HTTP 通信中起到了至关重要的作用,能够影响客户端和服务器的行为、性能、安全性等。
22. 对 websocket 的理解
WebSocket 是一种通信协议,它提供了在客户端和服务器之间进行双向通信的能力。与传统的 HTTP 请求-响应模式不同,WebSocket 可以在客户端和服务器之间建立一个持久的连接,从而实现实时的数据传输。
工作原理
握手(Handshake):
- 客户端通过 HTTP 请求发送一个
Upgrade
请求头,要求协议升级为 WebSocket。 - 服务器返回 101 状态码,协议升级成功。
- 客户端通过 HTTP 请求发送一个
双向通信:
- 连接建立后,客户端和服务器之间可以进行双向通信。
- WebSocket 连接是持久的,直到一方主动关闭连接。
数据传输:
- WebSocket 传输的数据可以是文本或二进制,采用帧(frame)机制,允许多次消息发送。
关闭连接:
- 客户端或服务器通过发送关闭帧终止连接,确保数据正确传输和连接正常关闭。
WebSocket 与 HTTP 的区别
特性 | WebSocket | HTTP |
---|---|---|
连接模式 | 双向、全双工通信 | 单向、请求/响应通信 |
协议类型 | 基于 TCP,持久连接 | 基于请求-响应模式,每次请求都需要建立连接 |
连接持久性 | 持久连接,直到手动关闭 | 每次请求都需要建立和关闭连接 |
效率 | 高效,减少了多次连接建立的开销 | 每次请求和响应都需要建立连接,消耗较大 |
延迟 | 低延迟,数据传输实时性高 | 延迟较高,每次请求都需要重新建立连接 |
适用场景 | 实时通信应用,如在线聊天、股票交易 | 普通的请求-响应场景,如网页加载、API 请求 |
优点
实时性强: WebSocket 支持双向通信,数据可以即时传输,适合实时交互式应用。
减少网络延迟和带宽消耗: 由于 WebSocket 连接是持久的,客户端和服务器之间无需频繁建立和断开连接,减少了延迟和带宽消耗。
高效数据传输: WebSocket 协议相比 HTTP 协议更加高效,减少了请求头的传输并支持小帧传输,提升了数据传输效率。
缺点
不支持跨域: WebSocket 连接默认不能跨域,需要 CORS 配置才能部分解决。
资源管理问题: WebSocket 连接是持久的,需要服务器管理大量连接,可能导致性能瓶颈。
浏览器支持: 虽然大多数现代浏览器支持 WebSocket,但一些较老的浏览器可能不支持。
典型应用场景
即时聊天应用: 支持实时消息推送和交流。
实时股票或金融市场数据: 实时更新股市和金融数据。
在线游戏: 提供低延迟、高效的双向通信。
协作编辑: 如 Google Docs,实时协作和文档同步。
WebSocket API
WebSocket API 是客户端与 WebSocket 服务器交互的 JavaScript 接口,提供了建立连接、发送消息和关闭连接等功能。
关键方法
new WebSocket(url)
:创建一个新的 WebSocket 连接。.send(data)
:发送数据到服务器。.close(code, reason)
:关闭 WebSocket 连接。
事件
onopen
:连接成功建立时触发。onmessage
:接收到服务器的消息时触发。onerror
:发生错误时触发。onclose
:连接关闭时触发。
总结
WebSocket 是一种高效的实时通信协议,适用于需要低延迟、双向通信和持久连接的应用。与 HTTP 协议相比,WebSocket 提供了更为灵活和实时的数据交换能力,成为现代 Web 应用中不可或缺的一部分。
TCP/IP 与 OSI 模型对比
OSI 七层模型
OSI 层次 | 功能描述 |
---|---|
物理层 | 负责数据的物理传输,包括电缆、无线信号等。 |
数据链路层 | 负责相邻节点间的通信,进行数据帧封装、错误检测和流量控制。 |
网络层 | 负责数据包的路由和转发,确保数据从源端到达目的地,使用 IP 协议。 |
传输层 | 负责端到端的通信,提供可靠或不可靠的数据传输,主要协议有 TCP 和 UDP。 |
会话层 | 负责建立、管理和终止会话连接,确保进程之间的同步。 |
表示层 | 负责数据的格式化、加密和解密,确保数据在不同系统间正确传输。 |
应用层 | 提供应用服务,如网页浏览、电子邮件、文件传输等,常见协议有 HTTP、FTP、SMTP 等。 |
23. TCP/IP 四层模型
TCP/IP 层次 | 功能描述 |
---|---|
网络接口层 | 对应 OSI 模型中的物理层和数据链路层,负责物理设备和网络之间的数据传输。 |
互联网层 | 对应 OSI 模型中的网络层,负责数据包的路由和转发,使用 IP 协议。 |
传输层 | 对应 OSI 模型中的传输层,负责端到端的数据传输,主要协议为 TCP 和 UDP。 |
应用层 | 对应 OSI 模型中的应用层、表示层和会话层,负责提供应用服务,如 HTTP、FTP、SMTP 等。 |
对比总结
OSI 层次 | TCP/IP 层次 | 功能描述 |
---|---|---|
物理层 | 网络接口层 | 传输原始比特数据,负责硬件通信 |
数据链路层 | 网络接口层 | 数据帧的封装与错误检测、流量控制 |
网络层 | 互联网层 | 数据包的路由和转发,使用 IP 协议 |
传输层 | 传输层 | 提供端到端的通信服务,使用 TCP 或 UDP |
会话层 | 应用层 | 提供进程间通信的管理、同步 |
表示层 | 应用层 | 数据的加密、压缩和格式化 |
应用层 | 应用层 | 提供实际的应用服务,如 HTTP、FTP 等 |
总结
- OSI 七层模型:提供详细的层次结构,适用于理论和网络协议的研究。
- TCP/IP 四层模型:简化的协议栈,更贴近实际应用,广泛用于互联网通信。
TCP/IP 模型是实际网络中使用的标准协议栈,而 OSI 模型则更多用于理论教学和研究。
24. 即时更新方案对比
方案 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
轮询(Polling) | 数据变化不频繁,适用于简单的实时更新 | 实现简单,兼容性好,易于实现 | 服务器负载大,数据更新延迟长,带宽浪费 |
长轮询(Long Polling) | 数据更新不频繁,客户端需要及时获取变化 | 减少了轮询请求次数,提升了更新的实时性 | 连接保持时间较长,仍有超时问题,可能造成资源浪费 |
WebSocket | 高频、低延迟的实时通信(如在线游戏、即时聊天) | 双向实时通信,低延迟,持久连接,服务器可主动推送数据 | 实现复杂,无法跨域通信,连接数管理复杂 |
Server-Sent Events (SSE) | 单向推送数据(如实时新闻、股市数据更新) | 实现简单,基于 HTTP 协议,自动重连,适合单向数据推送 | 仅支持单向通信(服务器到客户端),仅限 HTTP/1.1 协议 |
Firebase / Pusher | 快速构建实时应用(如聊天应用、实时通知) | 无需自己搭建服务器,API 和 SDK 简单易用,开发速度快 | 需要付费,控制力较差,可能受服务商限制 |
WebRTC | 音视频和点对点数据传输(如视频会议、P2P 应用) | 低延迟,支持点对点传输,减少服务器负载 | 实现复杂,需要信令服务器,浏览器支持问题 |
GraphQL 订阅(Subscriptions) | 实时数据更新(如社交网络,实时分析) | 支持客户端订阅数据变化,自动接收更新 | 实现复杂,后端需要支持 WebSocket 或其他推送技术 |
MQTT | 物联网(IoT)、实时消息传递 | 轻量级,高效,适合低带宽和低功耗的设备,支持发布/订阅模式 | 需要额外的 MQTT 服务器,传输大数据量时效率较低 |
总结
- 轮询 和 长轮询 适合简单的实时更新,但存在带宽浪费和延迟问题。
- WebSocket 是一个强大的实时双向通信协议,适合大多数实时通信应用。
- SSE 适用于单向数据流的实时推送,但仅限 HTTP/1.1 协议。
- 第三方服务如 Firebase 和 Pusher 提供快速实现的方案,适合需要快速开发的项目。
- WebRTC 适用于需要低延迟的音视频通信和点对点数据传输。
- GraphQL 订阅 适合需要订阅式数据更新的应用,特别适合与现有 GraphQL API 集成。
- MQTT 适合物联网和低带宽环境,支持发布/订阅模型。
根据具体需求,选择合适的技术实现实时更新。
25. HTTPS 加密的过程
HTTPS 加密过程
客户端发起 HTTPS 请求:
- 客户端(通常是浏览器)通过 HTTPS 协议向服务器发送请求时,会向服务器的 443 端口发起连接。
服务器返回证书:
- 服务器响应客户端请求,返回其数字证书(SSL/TLS 证书)。该证书由一个受信任的证书颁发机构(CA)签发,并包含服务器的公钥。
客户端验证证书:
- 客户端收到服务器的证书后,会验证该证书的有效性,包括证书是否过期、证书是否被篡改、证书是否由受信任的 CA 签发等。
- 客户端会通过系统中预安装的信任根证书列表(CA 证书)来验证证书的合法性。
密钥交换过程:
- 服务器和客户端通过 Diffie-Hellman 或 RSA 算法进行密钥交换。这个过程用于生成一个对称密钥,用于后续加密和解密数据。
- 在此过程中,客户端使用服务器公钥加密随机生成的对称密钥,并将其发送给服务器。
- 服务器使用自己的私钥解密出对称密钥。此时,客户端和服务器都持有相同的对称密钥(也称会话密钥)。
加密通信:
- 客户端和服务器使用共享的对称密钥进行加密和解密数据。此时,所有后续的数据传输都是加密的,防止被第三方窃听或篡改。
数据传输:
- 通过加密的通信通道进行数据交换,保证数据的保密性、完整性和认证。
如何验证证书的合法性
HTTPS 在传输加密的过程中,证书的验证是非常关键的一步。以下是客户端如何验证证书合法性的过程:
检查证书是否有效:
- 客户端首先检查证书的有效期,确保证书没有过期。如果证书过期,客户端会发出警告并阻止连接。
- 证书的有效期包括 生效日期 和 过期日期。
验证证书的签名:
- 客户端使用证书颁发机构(CA)的公钥验证服务器证书的签名。如果证书的签名合法,证明该证书在签发后未被篡改。
- 验证证书时,客户端会查找证书颁发机构(CA)的证书,通常是操作系统或浏览器中预装的受信任的根证书。
验证证书链:
- 客户端通过证书链验证证书是否合法。证书链是从服务器证书到根证书的路径,客户端需要确保每一层证书都有效。
- 如果证书链中的任何证书无效,验证失败,客户端会警告用户。
域名匹配:
- 客户端检查证书中的 Common Name (CN) 或 Subject Alternative Name (SAN) 是否与正在访问的域名匹配。如果不匹配,证书无效,客户端会发出警告。
检查撤销状态:
- 客户端检查证书是否被撤销,通常通过在线证书状态协议(OCSP)或证书撤销列表(CRL)进行检查。如果证书已被撤销,客户端会警告并阻止连接。
Nginx 配置
# ----------HTTPS配置-----------
server {
# 监听HTTPS默认的443端口
listen 443;
# 配置自己项目的域名
server_name www.xxx.com;
# 打开SSL加密传输
ssl on;
# 输入域名后,首页文件所在的目录
root html;
# 配置首页的文件名
index index.html index.htm index.jsp index.ftl;
# 配置 数字证书
ssl_certificate certificate/xxx.pem;
# 配置 服务器私钥
ssl_certificate_key certificate/xxx.key;
# 停止通信时,加密会话的有效期,在该时间段内不需要重新交换密钥
ssl_session_timeout 5m;
# TLS握手时,服务器采用的密码套件
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# 服务器支持的TLS版本
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 开启由服务器决定采用的密码套件
ssl_prefer_server_ciphers on;
location / {
try_files $uri $uri/ /html/index.html;
}
}
# ---------HTTP请求转HTTPS-------------
server {
# 监听HTTP默认的80端口
listen 80;
# 如果80端口出现访问该域名的请求
server_name www.xxx.com;
# 将请求改写为HTTPS(这里写你配置了HTTPS的域名)
rewrite ^(.*)$ https://www.xxx.com;
}
总结
HTTPS 的加密过程确保了数据在传输过程中是保密的、完整的,并且通信双方是经过认证的。通过使用 SSL/TLS 协议,客户端和服务器能够安全地交换信息。在验证证书的合法性时,客户端需要确保证书有效、签名正确、证书链完整、域名匹配以及证书未被撤销。
26. http1.x 在 http 1.0 上做了哪些优化
优化项 | HTTP/1.0 | HTTP/1.1 | 优势 |
---|---|---|---|
持久连接(Persistent Connections) | 每个请求都需要重新建立连接 | 引入 Connection: keep-alive ,支持在同一连接上发送多个请求/响应 | 减少连接开销,提高性能 |
管道化(Pipelining) | 请求/响应按顺序进行,不支持并行请求 | 支持在一个连接中并行发送多个请求 | 提高请求并行性,减少等待时间,但兼容性较差 |
缓存控制 | 无缓存控制机制,较为简单 | 增加了 Cache-Control , Etag 等头部,允许更精确的缓存控制 | 提高缓存效率,减少不必要的数据传输 |
请求/响应头部 | 请求和响应头较少,灵活性低 | 增加了 Host , Transfer-Encoding 等新头部 | 支持虚拟主机,支持分块传输编码,提供更多灵活性 |
状态码 | 状态码较少,信息较为简单 | 引入了如 409 Conflict 、410 Gone 等更多状态码 | 错误信息更详细,有助于调试和异常处理 |
分块传输编码(Chunked Transfer Encoding) | 无支持,必须提前知道响应体大小 | 支持分块传输编码,不需要预知响应体大小 | 适用于动态内容传输,减少等待时间 |
连接管理 | 每个请求/响应都需要独立建立连接 | 支持 Connection: keep-alive ,保持连接 | 减少连接建立和断开的开销,提升性能 |
功能和灵活性 | 基本的 HTTP 方法 | 增加了更多 HTTP 方法,如 OPTIONS , TRACE | 支持更多应用场景,增强协议的功能性 |
总结
- HTTP/1.1 在 HTTP/1.0 基础上进行了多项优化,尤其是在连接管理、缓存控制和请求并行性方面,提升了性能和协议的灵活性。
- 通过引入持久连接、管道化、分块传输等功能,HTTP/1.1 更加高效,但仍存在队头阻塞等问题,最终需要通过 HTTP/2 来进一步优化。
27. http3.0
0RTT(就是数据包一来一回的时间消耗) 建立安全连接:基于 DH 秘钥交换算法,在第一个包就可以包含有效的应用数据,从而在连接延时有很大优势,可以节约数百毫秒的时间
RTT 包括三部分:往返传播时延、网络设备内排队时延、应用程序数据处理时延 连接迁移:http3.0 基于 UDP 实现,不依赖 TCP 五元组,QUIC 使用自己的 connection ID,即使网络五元组变化了,仍然可以维持连接。基于 QUIC 协议之下,我们在日常 wifi 和 4G 切换时,或者不同基站之间切换都不会重连,从而提高更好的体验
队头阻塞问题:TCP 本身也有队头阻塞问题,QUIC 协议是基于 UDP 协议实现的,在一条链接上可以有多个流,流与流之间是互不影响的,当一个流出现丢包影响范围非常小,从而解决队头阻塞问题。通俗来说就是:一个数据包影响了一堆数据包,它不来大家都走不了。
新的拥塞机制:因为替换成 UDP 了,所以需要提供新实现的基于 UDP 的拥塞控制能力
前向纠错:QUIC 每发送一组数据就对这组数据进行异或运算,并将结果作为一个 FEC 包发送出去,接收方收到这一组数据后根据数据包和 FEC 包即可进行校验和纠错。
特性热插拔:因为核心能力都在用户态实现的,不依赖内核,调整拥塞控制算法等行为都变得更为简单
前向安全问题: 前向安全指的是密钥泄漏也不会让之前加密的数据被泄漏,影响的只有当前数据,对之前的数据无影响。
PS: QUIC 含义:Quick UDP Internet Connections 的缩写,直译为快速 UDP 互联网连接。
28. 如何实现 token 无感刷新
无感刷新 Token 机制(自动刷新 Token)常用于基于 JWT(JSON Web Token)身份认证的系统中,通过使用 Refresh Token 来在 Access Token 过期时自动获取新的 Token,确保用户体验不受影响。
1. 流程概述
1.1 用户登录/首次请求时获取 Token
- 用户登录时,服务器返回 Access Token 和 Refresh Token。
- 这两个 Token 通常被存储在客户端(如 localStorage 或 sessionStorage,或者使用 HttpOnly cookies 增强安全性)。
1.2 请求数据时使用 Access Token
- 客户端在发起 API 请求时,使用 Access Token 作为身份验证凭证,将其放入请求头中。
1.3 自动检测 Token 是否过期
- 客户端会定期检查 Access Token 是否已过期。可以通过解码 JWT 来获取 exp(过期时间) 字段,检测是否接近过期。
1.4 Access Token 过期时自动刷新
- 当检测到 Access Token 即将过期时,客户端会在不打扰用户的情况下,使用 Refresh Token 向服务器请求新的 Access Token。
1.5 刷新 Access Token 请求
- 客户端向服务器发送请求,携带 Refresh Token,服务器验证该 Token 是否有效。如果有效,服务器返回新的 Access Token(以及可选的新的 Refresh Token)。
1.6 更新 Token 并重试请求
- 客户端收到新的 Access Token 后,更新本地存储的 Token,并重试之前因 Token 过期失败的请求。
1.7 错误处理
- 如果刷新 Refresh Token 失败(例如 Token 已失效),客户端应处理用户登出,或提示用户重新登录。
2. 关键要点
2.1 Refresh Token 存储
- Refresh Token 应存储在更安全的地方,如 HttpOnly cookies,避免 JavaScript 访问,防止 XSS 攻击。
2.2 过期检测和刷新
- 客户端需要定期或在每次请求前检查 Access Token 是否过期,并在过期前主动刷新 Token。
2.3 服务器处理
- 服务器需要处理刷新 Token 请求,验证 Refresh Token 的有效性,并返回新的 Access Token,如果需要,还可以返回新的 Refresh Token。
3. 总结
通过结合 JWT 和 Refresh Token,可以实现 无感刷新 Token。该机制确保了在 Access Token 过期时,客户端能够在后台自动获取新 Token,从而让用户体验保持流畅,避免频繁的重新登录。
示例 DEMO:
// 假设你已经有了以下函数来获取和设置 tokens
function getAccessToken() {
return localStorage.getItem('access_token');
}
function setAccessToken(token) {
localStorage.setItem('access_token', token);
}
function getRefreshToken() {
return localStorage.getItem('refresh_token');
}
function setRefreshToken(token) {
localStorage.setItem('refresh_token', token);
}
// 发送请求并自动刷新 token
async function requestWithToken(url, options = {}) {
// 1. 获取当前的 Access Token
let accessToken = getAccessToken();
// 2. 设置请求头
options.headers = options.headers || {};
options.headers['Authorization'] = `Bearer ${accessToken}`;
try {
// 3. 尝试发送请求
const response = await axios(url, options);
return response;
} catch (error) {
if (error.response && error.response.status === 401) {
// 4. 如果收到 401 错误(Access Token 过期),尝试刷新 token
const refreshToken = getRefreshToken();
try {
// 5. 使用 Refresh Token 获取新的 Access Token
const refreshResponse = await axios.post('/refresh-token', { refresh_token: refreshToken });
const newAccessToken = refreshResponse.data.access_token;
// 6. 更新新的 Access Token
setAccessToken(newAccessToken);
// 7. 重新发送之前的请求
options.headers['Authorization'] = `Bearer ${newAccessToken}`;
const retryResponse = await axios(url, options);
return retryResponse;
} catch (refreshError) {
// 如果刷新失败(例如 Refresh Token 失效),处理登出或重新登录
alert("Session expired. Please log in again.");
// 重定向用户到登录页面
window.location.href = '/login';
}
}
throw error; // 其他错误抛出
}
}
```