前言
http在应用程序通信中担任着数据传输和资源获取的重要角色,前端xdm你们对于http知道多少呢,快来补充在评论区吧
实现原理
对于HTTP的实现原理可以简单地描述为以下几个步骤:
步骤描述
客户端发起请求:客户端(通常是Web浏览器)向服务器发送HTTP请求。请求由以下几个部分组成:
- 请求方法:指定请求的类型,如GET、POST、PUT等。
- URL(Uniform Resource Locator):指定请求的资源的地址。
- 请求头(Headers):包含附加的元数据,如User-Agent、Content-Type等。
- 请求体(Body):在POST或PUT请求中,可以包含要发送给服务器的数据。
服务器处理请求:服务器接收到客户端发送的HTTP请求并进行处理。服务器根据请求的URL、方法和头部信息来确定要执行的操作。
服务器返回响应:服务器根据请求的处理结果生成HTTP响应并发送回客户端。响应由以下几个部分组成:
- 状态码(Status Code):表示请求的处理结果,如200表示成功、404表示未找到、500表示服务器错误等。
- 响应头(Headers):包含附加的元数据,如Content-Type、Cache-Control等。
- 响应体(Body):包含服务器返回给客户端的数据,如HTML、JSON、图像等。
客户端解析响应:客户端接收到服务器发送的HTTP响应后进行解析。客户端解析状态码和响应头,并根据需要处理响应体中的数据。
流程图
上述流程中,有以下几个步骤:
建立TCP连接
:客户端发起TCP连接请求,通过三次握手与服务器建立连接。发送HTTP请求
:客户端发送HTTP请求,包括请求行、请求头和请求体,其中请求行包含请求方法和URL等信息。接收HTTP请求
:服务器接收到客户端发送的HTTP请求。处理请求
:服务器根据请求的URL、方法和头部信息来处理请求,执行相应的操作。发送HTTP响应
:服务器生成HTTP响应,包括状态行、响应头和响应体,其中状态行包含状态码表示请求的处理结果。接收HTTP响应
:客户端接收到服务器发送的HTTP响应。关闭TCP连接
:客户端和服务器之间的TCP连接关闭,释放资源。
这个流程图描述了客户端和服务器之间的基本交互过程,展示了请求-响应模型和TCP/IP作为传输协议的使用方式。
请求方式
常用的请求方式有下面几种
(幂等(Idempotent)是指对同一资源进行多次操作,得到的结果与进行一次操作的结果是相同的)
GET方法
特点
:GET方法用于从服务器获取资源,是一种幂等的请求方法,即多次发送相同的GET请求,得到的结果应该是相同的。场景
:GET方法常用于获取数据,例如获取文章内容、获取用户信息等。它是最常见的请求方法,可以在浏览器中直接输入URL进行访问。
ini
const url = 'http://example.com/api/users';
fetch(url)
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
POST方法
特点
:POST方法用于向服务器提交数据,常用于新建资源或提交表单数据。与GET不同,POST请求不是幂等的,即多次发送相同的POST请求,可能会创建多个资源。场景
:POST方法常用于提交表单数据、创建新的资源或进行数据的持久化操作。例如注册新用户、发布文章等。
ini
const url = 'http://example.com/api/users';
const data = {
name: 'John Doe',
email: 'johndoe@example.com'
};
fetch(url, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
PUT方法
特点
:PUT方法用于向服务器更新资源,是一种幂等的请求方法,即多次发送相同的PUT请求,得到的结果应该是相同的。场景
:PUT方法常用于更新资源的全部内容。例如更新用户信息、修改文章内容等。
ini
const url = 'http://example.com/api/users/1';
const data = {
name: 'Updated Name',
email: 'updatedemail@example.com'
};
fetch(url, {
method: 'PUT',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
DELETE方法
特点
:DELETE方法用于从服务器删除资源,是一种幂等的请求方法,即多次发送相同的DELETE请求,得到的结果应该是相同的。场景
:DELETE方法常用于删除资源,例如删除用户、删除文章等。但需要谨慎使用,因为删除操作是不可逆的。
ini
const url = 'http://example.com/api/users/1';
fetch(url, {
method: 'DELETE'
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
概括
- GET方法用于获取资源,是幂等的,常用于读取数据。
- POST方法用于提交数据,不是幂等的,常用于创建资源或提交表单数据。
- PUT方法用于更新资源,是幂等的,常用于更新全部内容。
- DELETE方法用于删除资源,是幂等的,常用于删除数据。
请求头部
HTTP请求头部是非常重要的一部分。HTTP请求头部包含了关于请求的各种元数据信息,例如请求的方法、内容类型、身份验证等。
请求中设置/获取头部信息
js
// 创建一个新的XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 设置请求方法和URL
xhr.open('GET', 'https://api.example.com/data', true);
// 设置自定义请求头部
xhr.setRequestHeader('Authorization', 'Bearer your_token');
xhr.setRequestHeader('Content-Type', 'application/json');
// 监听请求状态变化
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// 请求成功,处理响应数据
var response = JSON.parse(xhr.responseText);
console.log(response);
// 获取响应头部信息
var contentType = xhr.getResponseHeader('Content-Type');
var server = xhr.getResponseHeader('Server');
console.log('Content-Type:', contentType);
console.log('Server:', server);
} else {
// 请求失败,处理错误信息
console.log('Error:', xhr.status);
}
}
};
// 发送请求
xhr.send();
常见的请求头
- Accept : 指定客户端可接受的响应内容类型,例如
Accept: application/json
表示客户端期望接收JSON格式的响应。 - Content-Type : 指定请求主体的内容类型,例如
Content-Type: application/json
表示请求主体中的数据是JSON格式的。application/x-www-form-urlencoded
:指示请求主体中的数据是 URL 编码的表单数据。multipart/form-data
:指示请求主体中的数据是多部分表单数据,常用于文件上传。text/plain
:指示请求主体中的数据是纯文本。 - Authorization : 用于身份验证的凭证信息,常用于发送身份验证令牌,例如
Authorization: Bearer your_token
。 - User-Agent: 标识客户端(浏览器、应用程序等)的用户代理字符串,用于服务器识别客户端类型和版本。
- Referer: 表示请求的来源页面的URL,常用于记录统计信息或进行防盗链等功能。
- Cookie : 包含了之前服务器通过
Set-Cookie
响应头部设置的cookie信息,用于在客户端和服务器之间传递状态信息。 Cache-Control
: 控制缓存行为,例如Cache-Control: no-cache
表示不缓存响应。Origin
: 表示请求的源头,用于跨域请求的安全验证。If-None-Match
: 带有实体标签(ETag)的条件请求,如果资源的ETag与指定的值匹配,则返回304 Not Modified,表示资源未修改。Content-Length
: 表示请求主体的长度(以字节为单位),用于服务器校验请求是否完整。
js
var xhr = new XMLHttpRequest();
var url = 'https://api.example.com/data';
// 设置Accept头部
xhr.setRequestHeader('Accept', 'application/json');
// 设置Content-Type头部
xhr.setRequestHeader('Content-Type', 'application/json');
// 设置Authorization头部
xhr.setRequestHeader('Authorization', 'Bearer your_token');
// 设置User-Agent头部
xhr.setRequestHeader('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36');
// 设置Referer头部
xhr.setRequestHeader('Referer', 'https://www.example.com');
// 设置Cookie头部
xhr.setRequestHeader('Cookie', 'session_id=your_session_id');
// 设置Cache-Control头部
xhr.setRequestHeader('Cache-Control', 'no-cache');
// 设置Origin头部
xhr.setRequestHeader('Origin', 'https://www.example.com');
// 设置If-None-Match头部
xhr.setRequestHeader('If-None-Match', 'your_etag');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
}
};
xhr.open('GET', url, true);
xhr.send();
状态码
HTTP状态码是Web服务器在处理请求时返回的3位数字代码,用于表示请求的结果状态。一定要学会看状态码含义,方便快速定位解决问题,下面列举一些常见的HTTP状态码并解释其含义
1xx(信息性状态码)
表示接收的请求正在处理。
diff
- 100 Continue:服务器已接收到请求的起始部分,客户端应继续发送剩余的请求。
- 101 Switching Protocols:服务器已理解客户端的请求,正在切换协议以完成请求。
2xx(成功状态码)
表示请求已成功被接收、理解和处理。
diff
- 200 OK:请求成功,服务器返回所请求的数据。
- 201 Created:请求成功,服务器创建了新的资源。
- 204 No Content:请求成功,但服务器没有返回任何内容。
3xx(重定向状态码)
表示需要执行附加的操作以完成请求。
diff
- 301 Moved Permanently:请求的资源已永久移动到新位置。
- 302 Found:请求的资源暂时移动到新位置。
- 304 Not Modified:客户端的缓存资源是最新的,可以直接使用缓存数据。
4xx(客户端错误状态码)
表示客户端发出的请求有错误。
diff
- 400 Bad Request:服务器无法理解客户端的请求。
- 401 Unauthorized:请求要求身份验证。
- 404 Not Found:请求的资源不存在。
5xx(服务器错误状态码)
表示服务器在处理请求时发生错误。
diff
- 500 Internal Server Error:服务器遇到了意外错误,无法完成请求。
- 503 Service Unavailable:服务器暂时无法处理请求,通常是由于超载或维护。
其他
上面只是一些常见的HTTP状态码,还有其他状态码可以根据不同的情况返回,看跟服务端你们是什么约定咯。
缓存
利用缓存来提高应用性能,并避免不必要的网络请求。
工作原理
- 客户端发送一个HTTP请求到服务器。
- 服务器处理请求并生成响应。
- 服务器在响应的HTTP头中添加缓存相关的头字段,如Cache-Control和Expires,来指示该响应是否可以缓存以及缓存的有效期限。
- 客户端接收到响应后,根据响应头中的缓存指令来判断是否可以缓存该响应。
- 如果响应可以缓存,客户端将响应存储在缓存中,以备将来使用。
- 当客户端需要再次请求相同的资源时,它会首先检查缓存。如果缓存中存在有效的副本,客户端将从缓存中获取响应,而不是向服务器发起新的请求。
- 如果缓存中的响应已经过期或被标记为无效,客户端将发送一个条件请求到服务器,以验证缓存中的响应是否仍然有效。
- 如果服务器确认缓存中的响应仍然有效,它将返回一个特殊的响应码(304 Not Modified),告诉客户端可以使用缓存的副本。
- 如果服务器确定缓存中的响应已过期或无效,它将生成一个新的响应,并将其发送回客户端。
示例
js
// 检查缓存中是否存在有效的副本
caches.match('http://example.com/api/data').then(cachedResponse => {
if (cachedResponse) {
// 缓存副本存在,检查是否过期
const cacheControl = cachedResponse.headers.get('Cache-Control');
if (cacheControl && cacheControl.includes('max-age')) {
const maxAge = parseInt(cacheControl.split('=')[1]);
const cacheExpiration = new Date(cachedResponse.headers.get('Expires')).getTime();
const currentTime = Date.now();
if (currentTime - cacheExpiration < maxAge * 1000) {
// 缓存副本仍然有效,直接返回缓存数据
return cachedResponse.json().then(data => {
renderData(data);
});
}
}
}
// 缓存副本不存在或已过期,发送请求到服务器获取最新数据
return fetch('http://example.com/api/data')
.then(response => {
// 检查响应状态码
if (response.status === 200) {
// 将响应存储在缓存中
caches.open('my-cache').then(cache => {
cache.put('http://example.com/api/data', response.clone());
});
// 处理响应数据
return response.json();
} else {
// 处理错误状态码
throw new Error('Request failed with status ' + response.status);
}
})
.then(data => {
// 使用响应数据进行页面渲染
renderData(data);
});
})
.catch(error => {
// 处理错误
console.error(error);
});
在上述示例中,我只满足了两个点
1、检查是否有缓存指令,有就设置数据缓存
2、检查是否缓存副本有效,有效则直接返回缓存数据,不再请求接口
实际使用时需要根据目标浏览器和平台的特性进行适配和调整。
安全性和HTTPS
确保前端应用程序的安全性非常重要,其中包括使用HTTPS协议进行加密通信以及防范常见的安全漏洞,如跨站脚本攻击(XSS)和跨站请求伪造(CSRF)。
HTTPS加密通信
HTTPS(Hypertext Transfer Protocol Secure)是HTTP的安全版本,通过使用SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议对通信进行加密。使用HTTPS可以提供以下安全保护:
- 数据加密:HTTPS使用加密算法对传输的数据进行加密,使得中间人无法轻易窃听或篡改数据。
- 身份验证:HTTPS使用数字证书来验证服务器的身份,确保通信的目标是预期的服务器,防止中间人攻击。
- 完整性保护:HTTPS使用消息摘要算法来检测数据是否在传输过程中被篡改。
跨站脚本攻击(XSS)
XSS攻击是一种利用网页应用程序未正确过滤、转义或验证用户输入的漏洞。攻击者通过在网页中插入恶意脚本,使得用户在浏览该页面时受到攻击。为防止XSS攻击,可以采取以下措施:
- 输入验证和过滤:确保用户输入的数据被正确验证和过滤,以防止恶意脚本的注入。
- 输出转义:在将用户输入的数据输出到网页时,对特殊字符进行转义,使其在浏览器中显示为正常文本而不是可执行脚本。
- 使用安全的编码方式:在编写网页应用程序时,使用安全的编码函数和库,如将用户输入的数据进行HTML编码或使用安全的模板引擎。
跨站请求伪造(CSRF)
CSRF攻击是一种利用用户已经认证的会话来执行未经授权的操作的攻击方式。攻击者通过诱导用户访问恶意网页或点击恶意链接,使得用户在不知情的情况下执行攻击者指定的操作。为防止CSRF攻击,可以采取以下措施:
- 验证来源:在处理敏感操作的请求时,验证请求的来源是否合法,可以使用CSRF令牌来验证请求是否来自预期的源。
- 添加随机性:每次生成的CSRF令牌都应该是随机的,以防止攻击者猜测或预测令牌的值。
- 限制敏感操作:对于执行敏感操作(如更改密码、删除数据等),要求用户进行额外的身份验证,如输入密码或提供其他身份凭证。
其他
除了上述措施,还有其他安全性最佳实践可以帮助提高前端应用程序的安全性,例如定期更新和维护应用程序、限制权限、实施访问控制、记录和监控日志等。同时,定期进行安全审计和漏洞扫描也是保持前端应用程序安全性的重要环节。
http版本重点内容
版本重要内容影响
HTTP/1.1
持久连接
:HTTP/1.1引入了持久连接(Keep-Alive),允许在单个TCP连接上发送多个HTTP请求和响应,减少了连接建立和断开的开销。这提高了性能和效率,减少了延迟。
流水线化
:HTTP/1.1支持请求的流水线化,允许客户端发送多个请求而无需等待每个请求的响应。这提高了并行处理能力,加快了页面加载速度。
增加了缓存机制
:HTTP/1.1引入了更强大的缓存机制,包括可缓存和不可缓存的响应、缓存验证等。这可以减少对服务器的请求次数,提升性能和响应速度。
HTTP/2
多路复用
:HTTP/2使用二进制分帧层来传输请求和响应,引入了多路复用功能,允许在单个连接上同时发送多个请求和响应。这消除了HTTP/1.1中的队头阻塞问题,提高了并发性能和效率。 首部压缩
:HTTP/2使用HPACK算法对请求和响应的首部进行压缩,减少了首部的传输大小,节省了带宽和连接时间。
服务器推送
:HTTP/2允许服务器主动推送资源给客户端,提前发送客户端可能需要的资源,减少了往返时间和延迟,提高了页面加载速度。
优化了TLS握手
:HTTP/2对TLS握手进行了优化,减少了握手时间和连接建立的延迟。
HTTP/3
基于UDP
:HTTP/3使用QUIC协议作为传输层,而QUIC基于UDP协议。UDP相比于TCP具有更低的延迟和更好的抗丢包能力,提供了更快的连接建立和数据传输。
0-RTT握手
:HTTP/3支持0-RTT(Zero Round Trip Time)握手,允许在已建立的连接上发送数据,减少了握手的延迟。
可靠性和流量控制
:HTTP/3使用QUIC协议提供了可靠性和流量控制的功能,可以更好地适应不稳定的网络环境,提供更好的性能和用户体验。
现状/趋势
HTTP/1.1:HTTP/1.1是目前最广泛使用的HTTP版本,几乎所有的浏览器和服务器都支持HTTP/1.1。它在市场上占据着主导地位,尤其是在旧版浏览器和服务器上仍然很常见。
HTTP/2:HTTP/2相对较新,但它的采用率在不断增加。大多数现代浏览器和服务器都已经支持HTTP/2,并且许多网站已经升级到HTTP/2以获得性能和效率的提升。根据统计数据,HTTP/2在全球范围内的采用率在持续增长。
HTTP/3:HTTP/3是最新的HTTP版本,它基于QUIC协议,相对于HTTP/2有更好的性能和稳定性。然而,由于HTTP/3的相对新颖性,它的采用率相对较低。目前,HTTP/3的支持主要集中在一些大型网站和服务提供商上,但预计随着时间的推移,HTTP/3的采用率将逐渐增加。
总结
千淘万漉虽辛苦,吹尽狂沙始到金
hey 今天的你学习了吗?