源本科技 | 码上会

网络框架 Axios 中的 PUT

2026/04/19
4
0

引言

PUT 和 PATCH 是 HTTP 规范中专门用于更新服务器资源的请求方法,二者核心区别在于更新语义,数据提交格式与 POST 完全通用,遵循相同的 Content-Type 规范。

语义区别

PUT

  • 定义:完整替换目标资源,属于全量更新

  • 规则:客户端必须传递资源的所有完整字段,服务端会用新数据完全覆盖旧数据

  • 特性:具有幂等性(多次执行相同请求,结果完全一致)

  • 场景:修改用户全部信息、覆盖整个配置文件、替换完整文档

PATCH

  • 定义:部分修改目标资源,属于增量更新

  • 规则:客户端仅传递需要修改的字段,未传递的字段保持原有数据不变

  • 特性:推荐设计为幂等性,非强制要求

  • 场景:修改用户头像、仅更新密码、单独修改状态字段

基础配置

所有请求方法共享基础配置,统一封装提升代码复用性:

import axios from "axios";

// 基础请求地址
const BASE_URL: string = "http://localhost:8080/";

// 统一类型定义,约束请求数据格式
type RequestData = Record<string, any>;

application/x-www-form-urlencoded

适用于简单文本数据的全量 / 部分更新,纯键值对传输。

PUT

/**
 * PUT 全量更新 - URL 编码格式
 * @param url 接口路径
 * @param data 完整资源数据
 */
const putFormUrlEncoded = async (url: string, data: RequestData) => {
  try {
    const res = await axios({
      url: BASE_URL + url,
      method: "put",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      data: new URLSearchParams(data),
    });
    console.log("PUT 更新成功", res.data);
  } catch (err) {
    console.error("PUT 请求失败", (err as Error).message);
  }
};

// 测试:传递用户全部完整信息
const userAllData = { id: 1, account: "admin", password: "123456", nickname: "管理员" };
putFormUrlEncoded("test/put", userAllData);

PATCH

/**
 * PATCH 部分更新 - URL 编码格式
 * @param url 接口路径
 * @param data 仅需修改的字段数据
 */
const patchFormUrlEncoded = async (url: string, data: RequestData) => {
  try {
    const res = await axios({
      url: BASE_URL + url,
      method: "patch",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      data: new URLSearchParams(data),
    });
    console.log("PATCH 更新成功", res.data);
  } catch (err) {
    console.error("PATCH 请求失败", (err as Error).message);
  }
};

// 测试:仅修改密码,其他字段保持不变
const userPatchData = { id: 1, password: "654321" };
patchFormUrlEncoded("test/patch", userPatchData);

application/json

前后端分离最常用格式,支持复杂嵌套数据,适配全量 / 部分更新。

PUT

/**
 * PUT 全量更新 - JSON 格式
 * @param url 接口路径
 * @param data 完整结构化资源数据
 */
const putJson = async (url: string, data: RequestData) => {
  try {
    const res = await axios({
      url: BASE_URL + url,
      method: "put",
      headers: { "Content-Type": "application/json" },
      data,
    });
    console.log("PUT JSON 更新成功", res.data);
  } catch (err) {
    console.error("PUT JSON 请求失败", (err as Error).message);
  }
};

// 测试:完整用户信息
const userJsonFull = { id: 1, account: "admin", password: "123456", age: 25, roles: ["admin"] };
putJson("test/put", userJsonFull);

PATCH

/**
 * PATCH 部分更新 - JSON 格式
 * @param url 接口路径
 * @param data 待修改的部分字段
 */
const patchJson = async (url: string, data: RequestData) => {
  try {
    const res = await axios({
      url: BASE_URL + url,
      method: "patch",
      headers: { "Content-Type": "application/json" },
      data,
    });
    console.log("PATCH JSON 更新成功", res.data);
  } catch (err) {
    console.error("PATCH JSON 请求失败", (err as Error).message);
  }
};

// 测试:仅修改年龄和角色
const userJsonPatch = { id: 1, age: 26, roles: ["user", "admin"] };
patchJson("test/patch", userJsonPatch);

multipart/form-data

适用于资源关联文件更新场景,如修改用户头像、替换资源附件。

PUT

/**
 * PUT 全量更新 - 表单文件格式
 * @param url 接口路径
 * @param data 包含文件/文本的完整资源
 */
const putMultipartFormData = async (url: string, data: RequestData) => {
  const formData = new FormData();
  Object.keys(data).forEach(key => formData.append(key, data[key]));

  try {
    const res = await axios({
      url: BASE_URL + url,
      method: "put",
      headers: { "Content-Type": "multipart/form-data" },
      data: formData,
    });
    console.log("PUT 文件上传更新成功", res.data);
  } catch (err) {
    console.error("PUT 文件请求失败", (err as Error).message);
  }
};

// 测试:完整替换用户信息 + 头像
const putFileData = {
  id: 1,
  account: "admin",
  avatar: new File(["avatar"], "avatar.png", { type: "image/png" }),
};
putMultipartFormData("test/put", putFileData);

PATCH

/**
 * PATCH 部分更新 - 表单文件格式
 * @param url 接口路径
 * @param data 仅需修改的文件/字段
 */
const patchMultipartFormData = async (url: string, data: RequestData) => {
  const formData = new FormData();
  Object.keys(data).forEach(key => formData.append(key, data[key]));

  try {
    const res = await axios({
      url: BASE_URL + url,
      method: "patch",
      headers: { "Content-Type": "multipart/form-data" },
      data: formData,
    });
    console.log("PATCH 文件更新成功", res.data);
  } catch (err) {
    console.error("PATCH 文件请求失败", (err as Error).message);
  }
};

// 测试:仅更新头像,不修改其他信息
const patchFileData = {
  id: 1,
  avatar: new File(["new-avatar"], "new-avatar.png", { type: "image/png" }),
};
patchMultipartFormData("test/patch", patchFileData);

其他补充

幂等性

  1. PUT 强制幂等:同一请求执行 1 次和 100 次,服务器资源状态完全相同

  2. PATCH 建议幂等:规范设计下,多次执行结果一致,非 HTTP 强制要求

格式选择规则

  1. 简单文本更新:优先 application/x-www-form-urlencoded

  2. 复杂结构化数据:必选 application/json

  3. 包含文件 / 二进制数据:必选 multipart/form-data

最佳实践

  1. 全量覆盖更新 → 使用 PUT

  2. 局部字段修改 → 使用 PATCH

  3. 严格遵循后端接口规范,请求方法与 Content-Type 必须匹配

  4. 统一封装请求函数,减少重复代码,提升可维护性

总结

  1. PUT = 全量替换:必须传完整资源数据,天生幂等

  2. PATCH = 部分修改:仅传需更新字段,灵活高效

  3. 数据格式与 POST 完全通用,按业务场景选择即可

  4. 实际开发中,优先使用 JSON 格式做接口交互,文件更新使用 form-data 格式