💡前端入门网络协议-HTTP/1.1

635 阅读8分钟

前言

我们平常开发中,使用最多的还是 HTTP/1.1,因为它是目前最广泛使用的版本。

所以这篇文章我们重点学习 HTTP/1.1 的使用,以及请求和响应的格式。

HTTP 请求格式

一个完整的 HTTP 请求包含四个部分:

  1. 请求行:第一行
  2. 请求头:第二行开始的多行
  3. 空行:头部和实体之间必须有空行
  4. 请求体(可选):最后一部分

打开浏览器的network面板,点击一个请求,可以看到请求行和请求头:

下面举个简单的例子,来理解下 HTTP/1.1 的请求格式:

POST /api/login HTTP/1.1                    // 请求行:方法 路径 协议版本
Host: www.example.com                       // 请求头开始
Content-Type: application/json              // 声明发送的数据格式
Content-Length: 39                          // 声明发送的数据长度
User-Agent: Mozilla/5.0                     // 浏览器信息
Accept: application/json                    // 期望返回的数据格式
                                           // 空行
{                                          // 请求体开始
    "username": "zhang",
    "password": "123"
}

上面是一个向/api/login 发送一个 POST 请求。请求体是一个 JSON 对象,包含用户名和密码。

请求行包含请求方法、路径和协议版本。请求头包含客户端发送的元数据,如内容类型、长度、用户代理等。空行用于分隔请求头和请求体。请求体包含实际发送的数据。

请求头的格式是:字段名: 字段值,字段名和字段值之间用一个空格分隔。像上面的:

Host: www.example.com
Content-Type: application/json
Content-Length: 39
User-Agent: Mozilla/5.0
Accept: application/json

请求头中有些字段是通用的,也是比较重要的,下面稍微介绍下:

常用请求头

  1. Host(必需的)
    • 指定请求的服务器域名
    • Host: api.example.com
  2. Content-Type(发送数据时需要)
    • 指定发送的数据格式
    • Content-Type: application/json
    • Content-Type: application/x-www-form-urlencoded
    • Content-Type: multipart/form-data(上传文件时使用)
  3. Content-Length(发送数据时需要)
    • 指定发送数据的长度(字节数)
    • Content-Length: 39
  4. Authorization(身份认证时需要)
    • 发送身份验证信息
    • Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
  5. Cookie(需要发送 cookie 时)
    • 发送存储在浏览器的 cookie
    • Cookie: sessionId=abc123; userId=789
  6. Accept(指定期望的响应格式)
    • Accept: application/json
    • Accept: text/html,application/xml
  7. User-Agent(浏览器信息)
    • User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)

这些除了Content-Type,Authorization,我们需要额外设置,其他都是浏览器自动设置的。

HTTP支持多种请求方法,常用的有GET、POST、PUT、DELETE等。

常见的请求方法

  1. GET: 获取资源
GET /api/users/1 HTTP/1.1
Host: api.example.com
  1. POST: 创建资源
POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "张三", "age": 18}
  1. PUT: 更新资源
PUT /api/users/1 HTTP/1.1
Content-Type: application/json

{"name": "张三", "age": 20}
  1. DELETE: 删除资源
DELETE /api/users/1 HTTP/1.1
Host: api.example.com

下面看个经典的前端fetch发送post请求的代码例子:

fetch('https://api.example.com/login', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer token666'
    },
    body: JSON.stringify({ username: 'zhang', password: '123' })
})

指定路径为https://api.example.com/login,请求方法为POST,请求头为Content-Type: application/jsonAuthorization: Bearer token666,请求体为{ username: 'zhang', password: '123' }

HTTP 响应格式

HTTP响应是服务器返回给客户端的数据,完全由服务器控制,客户端只能被动接收,无法控制。

HTTP 响应也包含四个部分:

  1. 状态行:第一行
  2. 响应头:第二行开始的多行
  3. 空行:头部和实体之间必须有空行
  4. 响应体:最后一部分

打开浏览器的network面板,点击一个请求,可以看到状态行和响应头:

下面举个简单的例子,来理解下 HTTP/1.1 的响应格式:

HTTP/1.1 200 OK                            // 状态行:协议版本 状态码 状态描述
Content-Type: application/json              // 响应头开始
Content-Length: 57                          // 响应数据的长度
Date: Mon, 23 May 2023 02:21:54 GMT        // 响应时间
Server: nginx/1.16.1                        // 服务器信息
                                           // 空行
{                                          // 响应体开始
    "code": 0,
    "data": {
        "token": "xxx666"
    }
}

上面是服务器返回的响应,状态码为200,表示请求成功,响应头包含内容类型、长度、日期、服务器信息等。响应体包含实际返回的数据。

读懂响应头的状态码很重要,是我们理解接口成功与否的关键窗口,除了200,常见的还有404、500等。

常见的状态码

  1. 2xx - 成功
    • 200 OK:请求成功
    • 201 Created:创建成功
    • 204 No Content:删除成功
  2. 3xx - 重定向
    • 301 Moved Permanently:永久重定向
    • 302 Found:临时重定向
    • 304 Not Modified:资源未修改
  3. 4xx - 客户端错误
    • 400 Bad Request:请求格式错误
    • 401 Unauthorized:未认证
    • 403 Forbidden:无权限
    • 404 Not Found:资源不存在
  4. 5xx - 服务器错误
    • 500 Internal Server Error:服务器内部错误
    • 502 Bad Gateway:网关错误
    • 503 Service Unavailable:服务暂时不可用

响应头的格式

响应头的格式和请求头的格式差不多,都是字段名: 字段值,字段名和字段值之间用一个空格分隔。

响应头中有些字段是通用的,也是比较重要的,下面稍微介绍下:

1. 缓存相关

  • Cache-Control: max-age=3600, public 。表示缓存控制
    • max-age:缓存时间(秒)
    • public:可以被任何缓存区缓存
    • private:只能被浏览器缓存
    • no-cache:每次都需要向服务器验证
    • no-store:不缓存任何内容
  • ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4" 表示资源的唯一标识符,用于验证缓存是否有效
  • Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT ,表示资源最后修改时间,也用于缓存验证

2. 内容相关

Content-Type: application/json; charset=utf-8 用来

返回内容的类型和编码

常见值:

  • text/html:HTML文档
  • application/json:JSON数据
  • text/plain:纯文本
  • image/jpeg:JPEG图片

Content-Length: 348

返回内容的长度(字节数)

Content-Encoding: gzip

内容的编码方式,常用于压缩

  • gzip:最常用的压缩方式
  • deflate:另一种压缩方式
  • br:专为 HTTP 优化的压缩算法

3. 跨域相关

Access-Control-Allow-Origin: *

允许跨域访问的域名

  • *:允许任何域名
  • example.com:只允许特定域名

Access-Control-Allow-Methods: GET, POST, PUT

允许的 HTTP 方法

Access-Control-Allow-Headers: Content-Type

允许的请求头

Access-Control-Max-Age: 86400

预检请求的有效期(秒)

4. 连接相关

Connection: keep-alive

连接是否保持

  • keep-alive:保持连接
  • close:关闭连接

Keep-Alive: timeout=5, max=1000

连接保持的参数

  • timeout:空闲时间(秒)
  • max:最大请求数

提示:

  1. 不是所有响应都需要包含所有这些头部
  2. 根据实际需求选择合适的响应头
  3. 可以通过浏览器开发者工具的 Network 面板查看实际的响应头

下面看一个JS中处理响应头和响应体的例子:

// 发送请求并处理响应
fetch('https://api.example.com/user/1', {
    method: 'GET',
    headers: {
        'Authorization': 'Bearer token666'
    }
})
.then(response => {
    // 1. 处理响应状态
    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    // 2. 查看响应头信息
    console.log('响应状态:', response.status); // 200
    console.log('内容类型:', response.headers.get('content-type')); // application/json
    console.log('内容长度:', response.headers.get('content-length')); // 348
    
    // 3. 处理响应体
    // response.json() 用于 JSON 数据
    // response.text() 用于文本数据
    // response.blob() 用于二进制数据(如图片)
    return response.json();
})
.then(data => {
    // 4. 使用响应数据
    console.log('用户数据:', data);
})
.catch(error => {
    // 5. 处理错误
    console.error('请求失败:', error);
});

提示:

  1. response.ok 为 true 表示状态码在 200-299 之间
  2. response.headers 是一个 Headers 对象,可以用 get() 方法获取特定头部
  3. response.json() 返回一个 Promise,需要用 await 或 then 处理
  4. 错误处理很重要,网络请求可能会失败

总结

本文详细介绍了 HTTP/1.1 协议的请求和响应格式,主要包括以下几个方面:

  1. HTTP 请求的组成
    • 请求行(方法、路径、协议版本)
    • 请求头(Host、Content-Type 等)
    • 空行
    • 请求体(可选)
  2. HTTP 响应的组成
    • 状态行(协议版本、状态码、状态描述)
    • 响应头(Content-Type、Cache-Control 等)
    • 空行
    • 响应体
  3. 重要的 HTTP 头部
    • 缓存相关:Cache-Control、ETag、Last-Modified
    • 内容相关:Content-Type、Content-Length
    • 跨域相关:Access-Control-Allow-Origin
    • 安全相关:Set-Cookie、X-Frame-Options
    • 连接相关:Connection、Keep-Alive
  4. 状态码的分类
    • 2xx:成功
    • 3xx:重定向
    • 4xx:客户端错误
    • 5xx:服务器错误
  5. 实际应用
    • 如何在前端发送 HTTP 请求
    • 如何处理响应状态和响应头
    • 如何处理响应数据
    • 如何进行错误处理

下篇文章我们来看看实际的前端工程化的项目中,如何请求接口的。这个是大家刚实习进入公司,拿到真实项目,遇到的最大的问题,语法我都会,但是项目中的这种写就很陌生,还要分什么开发环境,线上环境,真是头大。不过没关系,我们一起来看看