同源策略(Same-Origin Policy)是一种浏览器安全机制,用于限制一个网页从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。"同源"指的是协议(protocol)、域名(domain)和端口号(port)都相同。
同源策略的主要目的是防止恶意网站通过在用户浏览器中加载来自其他源的恶意代码,从而保护用户的隐私和安全。同源策略对以下几个方面进行了限制:
和 元素也受到同源策略的限制,无法直接访问其他源的内容。window.postMessage() 方法是唯一允许跨源窗口通信的标准机制,其他方式都受到同源策略的限制。虽然同源策略提高了安全性,但有时需要通过其他手段实现跨域资源共享。例如,使用 CORS(Cross-Origin Resource Sharing)标头允许服务器声明哪些来源是被允许的,以及哪些操作是被允许的。这样,服务器可以明确地指示浏览器绕过同源策略的限制。
CORS(Cross-Origin Resource Sharing)是一种机制,它使用额外的 HTTP 头来告诉浏览器,允许在一个 Web 页面上的脚本访问来自另一个域的资源。浏览器的同源策略限制了在一个域中加载的文档或脚本如何与来自另一个域的资源进行交互。CORS 通过在 HTTP 头中添加一些特定的字段来授权跨域请求。以下是 CORS 的关键组成部分:
Origin: http://example.comAccess-Control-Allow-Origin 字段,表示允许哪些来源的请求访问资源。可以是特定的域名,也可以是通配符 *,表示允许任意来源访问资源。Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Origin,还可能包括其他一些 CORS 相关的头部,例如:
Access-Control-Allow-Methods: 允许的 HTTP 方法。Access-Control-Allow-Headers: 允许的请求头。Access-Control-Allow-Credentials: 指定是否允许发送 Cookie。CORS 被广泛用于解决浏览器的同源策略限制,使得在跨域请求中能够安全地进行数据交互。在使用 CORS 时,服务器端需要配置相应的响应头,而客户端的请求会在浏览器中自动添加相应的请求头。
HTTP/2(Hypertext Transfer Protocol version 2)是 HTTP 协议的一个新版本,旨在提供更高的性能和更有效的数据传输。相对于 HTTP/1.1,HTTP/2 引入了一些重要的改进:
HTTP/2 的目标是通过引入这些改进,提高页面加载速度、降低延迟和带宽占用,从而提供更优秀的用户体验。虽然 HTTP/1.1 仍然是广泛使用的协议,但 HTTP/2 的特性对于现代 Web 应用的性能提升至关重要。
在HTTP中,队头阻塞问题通常指的是在使用持久连接的情况下,由于先前的请求响应未完成,后续的请求被阻塞等待。这主要涉及到HTTP/1.1中的管道(Pipeline)和HTTP/2中的多路复用(Multiplexing)。
解决HTTP中的队头阻塞问题的方法:
HTTP/2 解决队头阻塞问题的主要机制是多路复用(Multiplexing)。以下是 HTTP/2 中多路复用如何解决队头阻塞问题的关键点:
通过这些机制,HTTP/2 能够更有效地处理多个请求和响应,提高性能并减少队头阻塞的问题。但是 HTTP/2 只是解决了在应用层的队头阻塞,没有解决传输层 TCP 存在的队头阻塞。
流量控制(Flow Control) 和 拥塞控制(Congestion Control) 是两个不同的网络管理概念。
HTTP/2 中的处理:
在HTTP/2中,引入了一种流量控制机制,称为 流量控制窗口(Flow Control Window)。每个HTTP/2流(stream)都有自己的流量控制窗口,用于控制对应流上的数据流动。流量控制窗口的大小是动态调整的,接收方可以通过更新窗口大小来通知发送方可以发送的数据量。
另外,HTTP/2还使用了 多路复用(Multiplexing) 技术,允许在单个连接上同时发送多个请求和响应。这减少了连接的数量,减轻了网络拥塞的风险。每个流都有独立的流量控制窗口,因此一个流的拥塞不会影响其他流。
HTTP/3 是 HTTP 协议的最新版本,它的底层传输协议是基于 QUIC(Quick UDP Internet Connections)协议的。与 HTTP/2 相比,HTTP/3 引入了一些显著的变化:
总体而言,HTTP/3 主要通过引入 QUIC 协议来改进传输层的性能,以提高连接建立速度、降低延迟、增强连接的可靠性。虽然 HTTP/3 的使用逐渐增多,但它仍然处于逐步演进的阶段,需要服务器和客户端的支持,以及适应它的网络基础设施。
QUIC(Quick UDP Internet Connections)是一种由Google设计和开发的网络传输协议,旨在提供更快的连接建立和更低的延迟。以下是QUIC的一些关键特点和详细介绍:
WebSocket 是一种在单个持久连接上进行全双工通信的通信协议,用于在 Web 应用程序中实现实时的、双向的数据传输。WebSocket 协议在 RFC 6455 中定义。
与传统的 HTTP 请求-响应模型不同,WebSocket 允许客户端和服务器之间建立长时间的连接,双方可以随时发送数据,而不需要等待或重新建立连接。这使得 WebSocket 适用于需要低延迟和实时性的应用场景,如聊天应用、在线游戏、股票市场数据更新等。
一些与 HTTP 相比的 WebSocket 的特点包括:
尽管 WebSocket 提供了实时性的优势,但并不是适用于所有的场景。在一些场景下,仍然使用传统的 HTTP 请求-响应模型更为合适。WebSocket 主要用于弥补 HTTP 在实时性方面的不足。
HTTP 请求中的 OPTIONS 方法是用于描述目标资源与客户端或请求中指定的资源之间的通信选项。这个方法被广泛用于跨域资源共享(CORS)和预检请求(Preflight Request)。
一个常见的 CORS 预检请求的流程如下:
Access-Control-Allow-Methods、Access-Control-Allow-Headers 等。总体而言,OPTIONS 方法在 HTTP 中用于获取关于目标资源的通信选项,主要用于支持跨域请求时的预检和权限确认。
在HTTP报文头部中,"Host"字段是指定请求的目标主机的域名或IP地址。这字段是HTTP/1.1引入的,在请求报文中是必需的。
举例来说,如果客户端请求的URL是http://example.com/path/to/resource,那么"Host"字段的值应该是example.com。这样,服务器就能够识别客户端希望访问的是哪个域名下的资源。
在HTTP中,POST请求可以通过不同的方式传递数据,常见的方式有:
key1=value1&key2=value2的形式发送。POST /submit-form HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
key1=value1&key2=value2
Content-Type会指定为multipart/form-data,数据以多个部分的形式进行编码。POST /upload-file HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=---------------------------
-----------------------------123456789012345678901234
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain
...contents of example.txt...
-----------------------------123456789012345678901234--
POST /submit-json HTTP/1.1
Host: example.com
Content-Type: application/json
{
"key1": "value1",
"key2": "value2"
}
POST /submit-xml HTTP/1.1
Host: example.com
Content-Type: application/xml
value1
value2
HTTP 预连接(HTTP Prefetching)是一种通过提前获取与当前页面相关的资源的机制,以加速页面加载速度。预连接可以使浏览器在后台请求和获取页面可能需要的资源,从而提前缓存这些资源,减少用户点击链接或访问下一个页面时的延迟。
HTTP 预连接的主要目的是优化用户体验,降低页面加载时间,特别是对于那些在用户交互前就可以预测到的资源。
在 HTML 中,可以使用 元素来指定预连接的资源。例如:
<link rel="prefetch" href="https://example.com/image.jpg">
上述代码表示浏览器应该在后台提前获取 https://example.com/image.jpg 这个资源,以备将来可能需要使用。可以在页面的 部分中添加多个这样的 元素,以预连接多个资源。
除了 rel="prefetch",还有其他一些关系类型,例如 rel="preconnect"、rel="dns-prefetch" 等,用于指示浏览器在后台进行与连接有关的操作。这些关系类型的具体用法如下:
**rel="preconnect"**:
提示浏览器建立到指定资源的连接。适用于预先建立连接到域名,以减少后续请求的延迟。
<link rel="preconnect" href="https://example.com">
**rel="dns-prefetch"**:
提示浏览器进行 DNS 预解析,以缓存域名对应的 IP 地址,加速后续的连接建立。
<link rel="dns-prefetch" href="https://example.com">
这些预连接的技术可以在一定程度上加速网页加载,但需谨慎使用,不应滥用,以免增加不必要的网络负担。
连接重用是指在同一连接上进行多次 HTTP 请求和响应的过程。HTTP/1.1 引入了持久连接(persistent connection)机制,允许在单个连接上发送多个请求和接收多个响应,从而减少了连接的建立和关闭的开销,提高了性能。
在持久连接中,客户端和服务器都可以选择在请求头中包含 Connection: keep-alive,以指示它们希望保持连接打开,以备将来可能的请求。服务器也可以在响应头中包含 Connection: keep-alive,以确认连接将被保持打开。
连接重用的好处包括:
在使用持久连接时,需要注意以下几点:
总的来说,连接重用是通过持久连接机制实现的,它在一定程度上优化了HTTP协议,提高了性能,减少了资源浪费。
会话(Session) 和 持久性连接(Persistent Connection) 是两个在HTTP/HTTPS中有关联但不同的概念。
Connection: close。这允许在同一个TCP连接上发送多个请求和接收多个响应。区别:
HTTP 中的 Chunked 编码是一种用于传输不定长度数据的编码方式。它允许将数据分成一系列的块(chunks)进行传输,每个块都包含块的大小信息以及实际的数据。Chunked 编码主要用于在不知道整个消息长度的情况下传输数据,例如在流式传输或实时数据传输的场景。
Chunked 编码的基本工作原理如下:
Transfer-Encoding: chunked 字段,表明数据将以 Chunked 编码方式传输。示例:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
4
Wiki
6
pedia
E
in
\r\n
chunks.
0
\r\n
\r\n
上述示例中,“Wiki” 和 “pedia” 是两个块,它们的大小分别为 4 和 6。最后的块大小为 0,表示数据传输结束。
Chunked 编码的作用:
需要注意的是,并非所有服务器和客户端都支持 Chunked 编码,因此在使用时需要确保双方都支持这种传输编码方式。
HTTP/HTTPS性能优化可以通过多种策略来实现,以下是一些常见的优化策略:
预加载资源,或使用 预渲染关键页面。HTTP/1.1管线化(HTTP/1.1 Pipelining) 是一种优化技术,旨在减小因网络延迟而引起的性能损失。在不使用管线化时,客户端和服务器之间的每个请求都必须等待前一个请求的响应完成才能发送下一个请求。而使用管线化,多个请求可以在一个连接上同时进行,不需要等待前一个请求的响应。
工作原理:
GET /page1 HTTP/1.1
Host: example.com
GET /page2 HTTP/1.1
Host: example.com
GET /page3 HTTP/1.1
Host: example.com
上述例子中,三个请求通过同一个连接同时发送到服务器。
优势:
减小延迟: 由于多个请求可以在一个连接上并行处理,减小了每个请求之间的等待时间,降低了总体延迟。
注意事项:
响应顺序: 管线化中响应的顺序需要与请求的顺序相匹配,保证每个响应对应正确的请求。
不适用于所有场景: 管线化可能存在一些问题,例如队头阻塞(Head-of-Line Blocking)和不同请求可能对资源产生相互影响。因此,并非所有情况下都适用。
尽管HTTP/1.1管线化可以提高性能,但由于存在一些问题,并没有被广泛采用。后续的HTTP/2引入了更强大的多路复用机制,替代了管线化,更好地解决了并发请求的问题。
中继代理(Forward Proxy) 和 反向代理(Reverse Proxy) 是两种常见的代理服务器,它们在HTTP/HTTPS通信中扮演不同的角色。
Client --> [Forward Proxy] --> Internet --> Origin Server
Client --> [Reverse Proxy] --> Backend Servers
刷新(Refresh)和重定向(Redirect) 都是HTTP中用于导航或切换资源的机制,但它们有不同的用途和实现方式。
Refresh 字段,指定刷新的时间间隔和目标URL。Refresh 字段的响应头,客户端收到响应后会在指定时间后重新加载或跳转。HTTP/1.1 200 OK
Refresh: 5; url=http://example.com/new-page
Content-Type: text/html
Refresh Example
This page will refresh in 5 seconds.
HTTP/1.1 302 Found
Location: http://example.com/new-page
区别:
Refresh 字段实现,而重定向通过设置状态码和 Location 字段实现。协商缓存(Conditional GET) 是HTTP中一种用于减少不必要的数据传输的机制,它通过在请求头中携带一些条件,让服务器根据条件决定是否返回实体内容。
在协商缓存中,常用的条件包括:
工作流程:
客户端请求:
GET /resource HTTP/1.1
Host: example.com
If-None-Match: "abc123"
服务器响应:
HTTP/1.1 304 Not Modified
ETag: "abc123"
在上述例子中,客户端带有条件头If-None-Match,服务器根据资源的ETag判断资源是否发生变化,如果未变化则返回状态码304 Not Modified,否则返回实体内容。这样,服务器避免了传输重复的内容,减少了带宽占用。
负载均衡 是一种在网络中分配工作负载的技术,旨在确保所有服务器都能够有效地处理请求,避免某一台服务器过载而影响系统性能。在HTTP/HTTPS中,负载均衡常用于分发客户端请求到多个服务器,实现高可用性和性能优化。
常见的负载均衡算法:
总体原则: 选择合适的负载均衡算法取决于具体的应用场景和服务器性能特点,常常需要根据实际情况进行调优。
URL(Uniform Resource Locator) 和 URI(Uniform Resource Identifier) 都是用于标识和定位资源的标识符,但它们有一些区别:
mailto:john@example.com 是一个 URI,表示电子邮件地址。https://www.example.com/page 是一个 URL,表示一个网页的地址。总结:
在实际使用中,人们通常使用 URL 来表示资源的位置和定位方式,因为 URL 提供了更具体的信息,可以直接用于访问和定位网络上的资源。
HTTP TRACE 方法 是一种用于测试和诊断的 HTTP 请求方法,它会在经过的服务器上执行一个环回测试,服务器会将收到的请求消息发回给客户端,以便客户端查看请求在传输过程中是否发生了变化。
TRACE 请求的格式:
TRACE /path HTTP/1.1
Host: example.com
TRACE 可能会导致安全问题
由于 TRACE 的潜在安全问题,现代的Web服务器通常会默认禁用 TRACE 方法。在正式的生产环境中,建议将 TRACE 方法禁用以减少潜在的安全风险。
在 HTTP/1.1 中,没有明确定义请求和响应的最大大小。这通常由服务器和客户端的配置以及网络环境决定。
然而,一些常见的限制包括:
在实际应用中,为了防止滥用和提高性能,通常会对请求和响应的大小设置合理的限制。例如,防火墙、负载均衡器、Web服务器和应用程序服务器等都可能设置最大请求和响应大小。这些限制可以在配置文件或服务器软件的设置中进行调整。
浏览器会自动尝试请求网站的 favicon.ico 文件,这是一个小图标文件,通常显示在浏览器标签页上或书签列表中,以标识网站。浏览器默认将这个文件命名为 favicon.ico,并将其放置在网站的根目录下。
HTTP 请求:
当浏览器加载网页时,它会尝试自动请求 favicon.ico 文件。这个请求通常发生在加载页面的早期阶段,而且是隐式的,无需在 HTML 中明确引用。请求的 URL 通常是网站的根目录,如 http://example.com/favicon.ico。
HTTPS 中的注意事项:
在使用 HTTPS 的情况下,为了确保安全,浏览器会尝试请求 HTTPS 版本的 favicon.ico,即 https://example.com/favicon.ico。如果网站没有提供 HTTPS 版本的 favicon.ico,浏览器可能会在控制台或网络面板中显示警告,但不会影响网页的正常加载。
网站管理员可以通过在网站的根目录提供一个合适的 favicon.ico 文件,来自定义网站的图标。这个图标通常是一个小的图像文件,例如 16x16 像素或 32x32 像素的图标。
Range 是 HTTP 请求头部的一部分,用于指定客户端想要获取资源的某个范围(部分)而不是整个资源。这允许客户端在多次请求中逐步获取资源的部分,有助于节省带宽和提高效率。这通常用于支持断点续传或仅下载资源的一部分。
基本格式:
Range: =-
其中, 表示范围的单位,一般为 bytes, 表示范围的起始位置,可以是一个具体的字节位置,或者为空表示从资源的开头开始。
Range: bytes=500-999
表示客户端希望获取资源的字节范围是从500到999。
多范围请求:
HTTP/1.1 支持多范围请求,允许客户端一次请求多个不连续的范围。这通过在 Range 头部中使用逗号分隔的多个范围实现。
Range: bytes=500-999,1000-1499
表示客户端希望获取资源的两个不连续的范围,分别是500到999和1000到1499。
服务器响应:
如果服务器支持并能满足客户端请求的范围,它将返回 206 Partial Content 状态码,并在响应头部包含 Content-Range 表示实际发送的范围,如下所示:
Content-Range: bytes 500-999/1500
表示服务器发送的是资源的第500到999字节的部分,而整个资源的大小是1500字节。
需要注意的是,并非所有服务器和资源都支持范围请求,因此客户端在使用 Range 头部时应该检查服务器的响应以确定是否成功获取了部分资源。
User-Agent 是 HTTP 头部中的一个字段,用于标识发起请求的用户代理(User Agent),通常是一个浏览器或其他客户端应用程序的名称和版本信息。这个头部允许服务器根据用户代理来适应或定制响应,以提供更好的用户体验。
User-Agent 头部识别请求的客户端类型和版本,从而适应性地提供不同版本的网页或资源。这是为了解决不同浏览器之间的兼容性问题。User-Agent 来执行功能检测,以确定请求的客户端是否支持特定的功能或技术。User-Agent 头部来收集统计数据,了解其用户群体中使用的浏览器和设备分布情况。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
上述示例中,User-Agent 表示请求是由 Chrome 浏览器的版本 91.0.4472.124 在 Windows 操作系统上发起的。这使得服务器能够根据这个信息提供适合 Chrome 浏览器的响应。
HTTP Strict-Transport-Security(HSTS)是一个安全策略机制,旨在防止通过明文HTTP连接进行的中间人攻击。HSTS通过强制客户端和服务器使用加密的HTTPS连接来提高网站的安全性。
基本原理:
当服务器启用了HSTS,它会在响应头部中包含一个 Strict-Transport-Security 字段,其中包含了一些指令,主要告诉客户端:
Strict-Transport-Security: max-age=31536000; includeSubDomains
上述示例中,max-age 表示 HSTS 策略的有效期,单位是秒(这里是一年),includeSubDomains 表示包括所有子域名。
优势和作用:
需要注意的是,一旦启用了HSTS,客户端浏览器将会记住这个策略的有效期,即使网站之后禁用了HSTS。因此,网站在启用HSTS之前应确保其HTTPS设置正确,以免对用户造成不便。
HTTP/HTTPS的服务器推送(Server Push) 是一种优化性能的技术,允许服务器在客户端请求资源的同时,主动推送其他相关的资源给客户端,提前预加载可能需要的资源,从而减少客户端的等待时间。
服务器推送通常用于加速页面加载速度,减少延迟。它的工作方式如下:
<link rel="stylesheet" href="/styles.css" as="style" crossorigin="anonymous" onload="this.onload=null;this.rel='stylesheet'">
<link rel="preload" href="/styles.css" as="style" crossorigin="anonymous" />
<script src="/script.js" crossorigin="anonymous" defer>script>
<link rel="preload" href="/script.js" as="script" crossorigin="anonymous" />
在上述示例中, 和 标签中的 rel="preload" 属性表示对资源的预加载,而 rel="stylesheet" 和 defer 属性表示该资源是样式表或延迟执行的脚本。这样,服务器就可以通过推送这些资源来加速页面加载。
需要注意的是,服务器推送并不是在所有情况下都能带来性能提升,因为在一些网络环境下可能会产生冗余的推送,导致反而影响性能。因此,服务器推送的使用需要谨慎评估和调整。
Keep-Alive 和 Connection 是 HTTP 头部中与连接控制相关的两个字段,它们之间有一定的关系。
Keep-Alive 是一个用于控制持久连接(persistent connection)的 HTTP 头部字段。Connection: keep-alive 来启用持久连接。Keep-Alive 头部可以设置一些参数,如连接超时时间(timeout)、最大请求数等。Connection 头部用于指定连接的管理方式,其中包括与 Keep-Alive 有关的值。Connection: keep-alive,表示希望使用持久连接,保持 TCP 连接打开以供多个请求和响应复用。Connection: close,表示希望在完成请求或响应后立即关闭连接,不保持持久连接。Connection: keep-alive
上述示例中,Connection: keep-alive 表示请求或响应希望使用持久连接。
关系:
Connection: keep-alive。Connection: keep-alive。需要注意的是,并非所有的服务器和客户端都支持持久连接,因此 Connection 头部的处理要根据具体的 HTTP 实现来确定。如果服务器不支持持久连接,即使客户端请求中有 Connection: keep-alive,服务器也可能关闭连接。
HTTP/HTTPS中的协议升级(Protocol Upgrade)是一种机制,允许客户端和服务器在建立初始连接后将协议从一个初始协议升级到另一个协议。这种机制允许更高级别的协议在已经建立的连接上进行通信,而无需重新建立新的连接。
Upgrade 字段请求协议升级。服务器在确认后可以同意进行协议升级。GET /index.html HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
上述示例中,客户端通过 Upgrade: websocket 字段请求升级到 WebSocket 协议。
注意事项:
协议升级是一种灵活的机制,允许在已经建立的连接上切换到更高级别的通信协议,为一些特定的应用场景提供了更多的可能性。
子资源完整性(Subresource Integrity,简称SRI)是一种用于确保浏览器从第三方站点加载的资源(例如脚本或样式表)不被篡改的安全机制。SRI通过将资源的加密散列值嵌入到HTML文档中,允许浏览器验证实际加载的资源是否与所声明的完整性匹配。
integrity 属性将生成的哈希值嵌入到对应的资源引用中。integrity 值匹配。如果匹配,说明资源没有被篡改,加载继续进行;如果不匹配,浏览器会阻止加载资源,以防止潜在的攻击。<script src="https://example.com/script.js" integrity="sha256-BBQyUPoEhe1kOIfLcrTq2sBRHBEv3kqBaHai12j1fK4=" crossorigin="anonymous">script>
上述示例中,integrity 属性包含了资源文件 script.js 的SHA-256哈希值,浏览器在加载脚本时会检查实际的哈希值是否匹配。crossorigin="anonymous" 属性用于处理跨域请求。
优势和应用场景:
需要注意的是,SRI并不适用于所有场景,因为它增加了一些维护负担,并且需要确保资源的哈希值与实际文件的一致性。