HTTP (Hypertext Transfer Protocol) 是用于在网络上传输超文本的协议。它定义了客户端和服务器之间进行通信的规则。不同版本(HTTP/1.0、HTTP/1.1和HTTP/2)的HTTP协议存在一些区别。

HTTP 报文结构
HTTP 报文分为请求报文和响应报文两种类型,每种类型都有类似的结构:
请求报文
请求行 (Request Line)
请求头部 (Headers)
空行 (CRLF)
请求体 (Body)
响应报文
状态行 (Status Line)
响应头部 (Headers)
空行 (CRLF)
响应体 (Body)
常见的报文头部字段:
- Content-Type: 描述请求或响应中实际数据的媒体类型。它指示了传输的数据的种类,列如文本、图像、音频等。常见的值有:
- text/html: HTML 文档
- application/json: JSON 数据
- image/jpeg: JPEG 图像
- audio/mp3: MP3 音频
- Content-Length: 表明请求或响应体的长度,以字节为单位。用于确定要传输的数据的大小。
- User-Agent: 标识发起请求的客户端(浏览器、应用程序等)的用户代理信息。服务器可以根据该信息来适配不同类型的客户端。
- Host: 表明请求的目标主机名。在虚拟主机环境中,服务器可以通过这个字段确定请求应该被路由到哪个虚拟主机。
- Accept: 表明客户端能够接受的响应内容类型,以逗号分隔。服务器可以根据这个字段来选择最适合的响应类型。
- Cache-Control: 控制缓存行为的指令,可以控制缓存的存储、验证和过期等策略。
- Location: 在重定向响应中指定新的资源位置。当服务器返回 3xx 状态码时,可以使用此字段将客户端重定向到新的URL。
- Authorization: 包含用于进行身份验证的凭证信息。常见的形式是 Basic 认证,其中包含用户名和密码的 Base64 编码。
这些仅仅是HTTP报文头部中的一些常见字段,实际上还有许多其他字段,每个字段都具有不同的作用,用于指示请求或响应的各种属性和信息。

http的不同版本
HTTP/1.0:
- 发布年份:1996年
- 连接管理:每个请求/响应都需要单独的连接。每次请求都要重新建立连接,请求完成后连接关闭。
- 持久连接:支持持久连接,但需要在请求头中显式指定 Connection: keep-alive。
- 并发性:每个连接只能处理一个请求/响应,多个请求需要多个连接。
- 响应顺序:响应按照请求的顺序返回,一个请求的响应必须在前一个请求的响应之后返回。
- 请求优先级:不能指定请求的优先级,导致队头阻塞问题(Head-of-Line Blocking)。
- 压缩:不支持数据压缩,传输效率较低。
HTTP/1.1:
- 发布年份:1999年
- 连接管理:引入持久连接,每个连接可以处理多个请求/响应。默认使用持久连接,无需显式指定。
- 管道化:支持管道化请求,在一个连接上可以同时发送多个请求,但响应依旧需要按顺序返回。
- 并发性:一个连接可以并行处理多个请求,减少了连接建立的开销。
- 响应顺序:响应依旧按照请求的顺序返回,解决了队头阻塞问题。
- 请求优先级:依旧不能显式指定请求的优先级。
- 压缩:引入了对数据的压缩支持,如gzip,减少了传输的数据量,提高传输效率。
HTTP/2:
- 发布年份:2015年
- 连接管理:引入了多路复用,多个请求/响应可以在一个连接上同时进行,避免了连接建立的开销。
- 二进制传输:使用二进制格式取代HTTP/1.x中的文本格式,减少了解析开销。
- 头部压缩:引入了头部压缩机制,减少了传输的头部数据量。
- 服务器推送:服务器可以主动推送资源给客户端,避免了客户端发起额外的请求。
- 请求优先级:引入了请求优先级机制,允许指定请求的优先级,避免了队头阻塞问题。
- 安全性:强制使用加密,所有数据都通过TLS传输。
- 性能改善:通过上述特性,HTTP/2提供了更高的性能,减少了延迟,提高了页面加载速度。
总的来说,随着版本的升级,HTTP协议不断优化和改善,主要目标是提高性能、降低延迟,以适应现代web应用的需求。

如何支持不同版本的http协议,例如nodejs
如果开发者说他们的服务支持 HTTP/1.1,一般意味着他们的服务器和应用程序能够正确处理和响应遵循 HTTP/1.1 协议规范的请求和响应。
在 Node.js 中,您可以使用不同的库和模块来支持不同版本的 HTTP 协议。以下是使用 Node.js 来支持不同版本的 HTTP 协议的一些提议方法:
1. 使用内置的 http 和 https 模块: Node.js 提供了 http 和 https 内置模块,可用于创建 HTTP 和 HTTPS 服务器。这些模块默认支持 HTTP/1.1 协议。您可以使用以下代码创建一个简单的 HTTP 服务器:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, World!
');
});
server.listen(3000, () => {
console.log('Server listening on port 3000');
});
2. 使用第三方库支持 HTTP/2: 要支持 HTTP/2,您可以使用第三方库,如 spdy 或 http2 模块。以下是使用 spdy 模块创建 HTTP/2 服务器的示例:
const spdy = require('spdy');
const fs = require('fs');
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem')
};
const server = spdy.createServer(options, (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, HTTP/2!
');
});
server.listen(3000, () => {
console.log('HTTP/2 Server listening on port 3000');
});
3. 使用 Express 框架: 如果您更喜爱使用 Express 框架来构建应用程序,您可以根据需要配置 HTTP/1.1 或 HTTP/2。以下是一个简单的示例:
const express = require('express');
const spdy = require('spdy');
const fs = require('fs');
const app = express();
// For HTTP/1.1
app.get('/', (req, res) => {
res.send('Hello, HTTP/1.1!
');
});
// For HTTP/2
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem')
};
const http2Server = spdy.createServer(options, app);
http2Server.listen(3000, () => {
console.log('HTTP/2 Server listening on port 3000');
});
通过选择合适的模块和库,您可以在 Node.js 中轻松地支持不同版本的 HTTP 协议。根据您的需求和项目要求,选择合适的方法来进行实现。



