《Go 后端开发者学 React:前端 HTTP 请求详解》

前端 HTTP 请求详解:从原生 AJAX、Fetch API 到 Axios(Go 后端开发者入门)

一、先搞清楚三个概念

你之前写 Go 后端,应该很熟悉下面这个场景:

前端调用后端接口:

bash 复制代码
GET /api/users/1001

后端返回:

json 复制代码
{
  "id": 1001,
  "name": "张三",
  "age": 18
}

前端拿到数据之后,把用户名称显示到页面。

那么前端怎么发 HTTP 请求呢?

主要有三种方式:

  1. 原生 AJAX(XMLHttpRequest) :早期经典的 HTTP 请求方式。
  2. Fetch API:浏览器原生提供的现代 HTTP 请求接口。
  3. Axios:第三方 HTTP 请求库,对请求和响应做了进一步封装。

先看对比:

对比 XMLHttpRequest Fetch API Axios
是否浏览器原生 是 是 否,需安装
是否基于 Promise 否,传统事件回调 是 是
是否支持 async/await 需要自己封装 是 是
JSON 响应处理 通常手动解析 response.json() 通常自动解析
HTTP 404/500 需要检查状态码 不会自动 reject 默认会 reject
请求/响应拦截器 无内置机制 无内置机制 支持
使用复杂度 较高 较低 较低

现在开发 React 项目,重点掌握 Fetch API 和 Axios 即可。XMLHttpRequest 了解原理就行。


二、AJAX 到底是什么?

AJAX 全称:

Asynchronous JavaScript and XML

翻译:异步 JavaScript 和 XML。

虽然名字里面有 XML,但现在前后端通信主要使用 JSON。

1. 为什么需要 AJAX?

假设你访问一个用户管理页面,点击"查询用户"。

没有 AJAX 的传统页面交互方式可能是:

css 复制代码
用户点击查询
      ↓
浏览器请求服务器
      ↓
服务器返回整个新 HTML 页面
      ↓
浏览器加载新页面

而 AJAX 可以做到:

javascript 复制代码
用户点击查询
      ↓
JavaScript 发 HTTP 请求
      ↓
Go 后端返回 JSON
      ↓
JavaScript 获取数据
      ↓
更新页面中的用户信息

最大的区别:不需要为了获取新数据而重新加载整个网页。

注意,AJAX 是一种异步通信技术或开发方式,不是某一个具体的函数。

XMLHttpRequest、fetch()、Axios 都可以用于实现 AJAX 式的交互。

三、原生 AJAX:XMLHttpRequest

1. 最简单的 GET 请求

假设你的 Go 后端提供一个接口:

sql 复制代码
GET /api/user/1001

返回:

json 复制代码
{
  "id": 1001,
  "name": "张三"
}

前端代码:

javascript 复制代码
const xhr = new XMLHttpRequest();

// 1. 配置请求
xhr.open("GET", "/api/user/1001");

// 2. 请求完成时执行
xhr.onload = () => {
    if (xhr.status >= 200 && xhr.status < 300) {
        const user = JSON.parse(xhr.responseText);
        console.log(user.name);
    } else {
        console.error("HTTP 请求失败", xhr.status);
    }
};

// 3. 网络错误
xhr.onerror = () => {
    console.error("网络错误");
};

// 4. 发送请求
xhr.send();

逐行解释。

第一步:创建请求对象

ini 复制代码
const xhr = new XMLHttpRequest();

类似 Go 中准备一个 HTTP 请求相关对象。

第二步:配置请求

kotlin 复制代码
xhr.open("GET", "/api/user/1001");

表示使用 GET 方法,请求 /api/user/1001。

第三步:注册回调函数

ini 复制代码
xhr.onload = () => {
    console.log(xhr.responseText);
};

这里很关键:onload 是一个回调函数,等请求完成后才执行。

第四步:发送请求

ini 复制代码
xhr.send();

正式发送 HTTP 请求。

2. XMLHttpRequest 的问题

代码比较繁琐,需要自己处理:

  • 请求状态。
  • 成功和失败的回调。
  • JSON 字符串解析。
  • 网络错误和超时。

所以现代项目通常更倾向于 Fetch API 或 Axios。


四、Fetch API:现代浏览器原生请求方式

Fetch API 是浏览器内置的 HTTP 请求接口。

不需要通过 npm 安装依赖。

1. 最简单的 GET 请求

ini 复制代码
fetch("/api/user/1001")
    .then(response => response.json())
    .then(user => {
        console.log(user.name);
    });

和 XMLHttpRequest 相比,明显简单了。

但是你前面学习过 Promise 和 async/await,可以写得更直观。

2. Fetch + async/await(推荐)

typescript 复制代码
interface User {
    id: number;
    name: string;
}

async function getUser(): Promise<User> {
    const response = await fetch("/api/user/1001");

    if (!response.ok) {
        throw new Error(`请求失败: ${response.status}`);
    }

    const user: User = await response.json();

    return user;
}

调用:

javascript 复制代码
async function main() {
    const user = await getUser();

    console.log(user.name);
}

main();

这里有几个核心知识点。

① fetch()

scss 复制代码
fetch("/api/user/1001")

表示向后端发送 HTTP 请求,默认是 GET 方法。

② await fetch()

ini 复制代码
const response = await fetch("/api/user/1001");

fetch() 返回一个 Promise。

await 等待 HTTP 响应到达,得到 Response 对象。

③ response.json()

ini 复制代码
const user = await response.json();

把响应体中的 JSON 解析为 JavaScript 数据。

注意:response.json() 本身也是异步的,因此要使用 await。

④ response.ok

javascript 复制代码
if (!response.ok) {
    throw new Error("请求失败");
}

fetch() 遇到 HTTP 404、500 时,通常不会自动抛出异常。

因此需要自己检查 HTTP 状态。

3. Fetch POST 请求

假设后端提供:

bash 复制代码
POST /api/user
Content-Type: application/json

请求参数:

json 复制代码
{
  "name": "张三",
  "age": 18
}

Fetch 写法:

php 复制代码
async function createUser() {
    const response = await fetch("/api/user", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            name: "张三",
            age: 18
        })
    });

    if (!response.ok) {
        throw new Error("创建失败");
    }

    return response.json();
}

这里:

  • method:HTTP 方法。
  • headers:请求头。
  • body:请求体。
  • JSON.stringify():把 JavaScript 对象转换为 JSON 字符串。

4. 与 Go HTTP Client 对比

Go:

css 复制代码
data := map[string]any{
    "name": "张三",
    "age": 18,
}

body, _ := json.Marshal(data)

req, _ := http.NewRequest(
    "POST",
    "http://localhost:8080/api/user",
    bytes.NewReader(body),
)

req.Header.Set("Content-Type", "application/json")

TypeScript:

php 复制代码
const response = await fetch("/api/user", {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        name: "张三",
        age: 18
    })
});

两段代码的思路基本一致。


五、Axios:第三方 HTTP 请求库

Axios 是一个基于 Promise 的 HTTP 客户端。

可以在浏览器和 Node.js 环境中使用。

相比 Fetch,它提供了很多开箱即用的功能,例如:

  • 自动处理常见 JSON 响应。
  • 请求和响应拦截器。
  • 默认 HTTP 错误状态处理。
  • 统一配置请求地址、请求头等。

1. 安装 Axios

npm:

复制代码
npm install axios

pnpm:

csharp 复制代码
pnpm add axios

然后导入:

javascript 复制代码
import axios from "axios";

2. Axios GET 请求

typescript 复制代码
import axios from "axios";

interface User {
    id: number;
    name: string;
}

async function getUser(): Promise<User> {
    const response = await axios.get<User>("/api/user/1001");

    return response.data;
}

调用:

javascript 复制代码
async function main() {
    const user = await getUser();

    console.log(user.name);
}

main();

重点看:

csharp 复制代码
axios.get<User>("/api/user/1001")

这里的 <User> 是你前面学过的 TypeScript 泛型。

它告诉 TypeScript:这个接口的响应数据按 User 类型处理。

注意:这个泛型只负责静态类型检查,不能保证服务器真的返回符合 User 结构的数据。

3. Axios POST 请求

csharp 复制代码
async function createUser() {
    const response = await axios.post("/api/user", {
        name: "张三",
        age: 18
    });

    return response.data;
}

和 Fetch 对比:

Fetch:

css 复制代码
await fetch("/api/user", {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        name: "张三",
        age: 18
    })
});

Axios:

php 复制代码
await axios.post("/api/user", {
    name: "张三",
    age: 18
});

Axios 会帮你处理常见的 JSON 请求体序列化和对应请求头。

4. Axios 最重要的区别:response.data

Fetch:

ini 复制代码
const response = await fetch("/api/user/1001");
const user = await response.json();

Axios:

ini 复制代码
const response = await axios.get("/api/user/1001");
const user = response.data;

注意:

Fetch 的 response.json() 是异步方法,Axios 的 response.data 是已经处理好的响应数据。

六、Axios 的实际项目用法

真实业务中,一般不会在每个地方都重新写完整的请求配置。

而是统一封装 HTTP 客户端。

1. 创建 Axios 实例

javascript 复制代码
// request.ts
import axios from "axios";

export const request = axios.create({
    baseURL: "/api",
    timeout: 10000
});

这里:

  • baseURL:接口基础路径。
  • timeout:请求超时时间,单位毫秒。

例如:

vbscript 复制代码
request.get("/users");

对应的请求路径是:

bash 复制代码
/api/users

2. 请求拦截器

ini 复制代码
request.interceptors.request.use(config => {
    const token = sessionStorage.getItem("token");

    if (token) {
        config.headers.set("Authorization", `Bearer ${token}`);
    }

    return config;
});

请求拦截器的作用是:

在真正发送 HTTP 请求之前,对请求配置进行统一处理。

例如自动添加认证信息、请求 ID 等。

这里仅展示机制。生产环境中 Token 的存储与传递应遵循项目既有的安全方案。

3. 响应拦截器

vbscript 复制代码
request.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        console.error("请求失败", error);
        return Promise.reject(error);
    }
);

响应拦截器可以统一处理错误、日志以及业务响应结构。

Promise.reject(error) 表示返回一个失败状态的 Promise,把错误继续传递给调用方。

4. 在业务代码中调用

typescript 复制代码
// userApi.ts
import { request } from "./request";

interface User {
    id: number;
    name: string;
}

export async function getUser(id: number): Promise<User> {
    const response = await request.get<User>(`/users/${id}`);

    return response.data;
}

这样其他组件不需要关心 Axios 的底层配置,只需要调用 getUser()。


七、在 React 中怎么使用 Axios?

这才是你工作中最需要掌握的部分。

假设要开发一个用户信息页面。

typescript 复制代码
import { useEffect, useState } from "react";
import { getUser } from "./userApi";

interface User {
    id: number;
    name: string;
}

export default function UserPage() {
    const [user, setUser] = useState<User | null>(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState("");

    useEffect(() => {
        let active = true;

        async function loadUser() {
            try {
                const data = await getUser(1001);

                if (active) {
                    setUser(data);
                }
            } catch {
                if (active) {
                    setError("查询失败");
                }
            } finally {
                if (active) {
                    setLoading(false);
                }
            }
        }

        loadUser();

        return () => {
            active = false;
        };
    }, []);

    if (loading) {
        return <div>加载中...</div>;
    }

    if (error) {
        return <div>{error}</div>;
    }

    return <div>用户名:{user?.name}</div>;
}

你暂时不需要全部记住,先理解执行流程:

scss 复制代码
React 组件加载
      ↓
useEffect 执行
      ↓
调用 getUser(1001)
      ↓
Axios 发送 HTTP 请求
      ↓
Go 后端返回 JSON
      ↓
setUser(data) 更新状态
      ↓
React 重新渲染组件
      ↓
页面显示用户名

这里串联了你前面学过的几个知识点:

  • async/await:异步等待请求结果。
  • Promise<User>:声明异步返回结果的类型。
  • interface User:描述后端返回的数据结构。
  • useState:保存用户数据。
  • useEffect:处理组件加载后的数据获取。
  • setUser():更新状态,触发页面重新渲染。

八、三个工具的底层关系

容易有一个误解:

AJAX、Fetch、Axios 是三套完全不同的网络通信协议吗?

不是。

它们使用的仍然是 HTTP/HTTPS。

区别主要是前端如何组织和发送请求。

markdown 复制代码
                  前端业务代码
                       │
        ┌──────────────┼──────────────┐
        │              │              │
        ▼              ▼              ▼
 XMLHttpRequest      Fetch          Axios
        │              │              │
        └──────────────┼──────────────┘
                       ▼
                 浏览器网络能力
                       │
                       ▼
                    HTTP
                       │
                       ▼
                    Go 后端

Axios 是更高层的 HTTP 客户端封装,在浏览器端通常可以通过 XMLHttpRequest 等适配器实现网络请求,也可以在支持的环境中使用 Fetch 适配器。

因此不能简单理解为 Axios 一定基于 Fetch。

九、开发时到底选哪个?

使用场景 推荐方案
学习 HTTP 请求原理 XMLHttpRequest
原生浏览器项目 Fetch API
简单接口调用 Fetch API
React + TypeScript 业务项目 Fetch 或 Axios
需要统一拦截器和请求配置 Axios
项目已经有 request 封装 优先沿用项目现有方案

对于你目前工作中的 React 项目,建议先检查有没有这样的文件:

css 复制代码
src/
├── api/
│   ├── request.ts
│   └── user.ts
├── services/
│   └── task.ts
└── pages/
    └── TaskPage.tsx

如果已有统一请求工具,应该优先复用,而不是自己另外引入 Axios。

十、最后总结

你现在需要记住的其实只有三套写法。

1. XMLHttpRequest:回调方式

ini 复制代码
const xhr = new XMLHttpRequest();

xhr.open("GET", "/api/user");

xhr.onload = () => {
    console.log(xhr.responseText);
};

xhr.send();

2. Fetch:原生 Promise 方式

ini 复制代码
const response = await fetch("/api/user");
const data = await response.json();

3. Axios:第三方封装方式

ini 复制代码
const response = await axios.get("/api/user");
const data = response.data;

一句话总结:

AJAX 是异步请求技术的概念,XMLHttpRequest 是传统浏览器 API,Fetch 是现代原生请求 API,而 Axios 是更方便的第三方 HTTP 客户端。

对 Go 后端开发者而言,真正要掌握的是:如何发请求、如何解析 JSON、如何处理异常,以及如何把返回数据交给 React 组件显示。

相关推荐
Penge6669 小时前
《Go 后端开发者学 React:组件通信与插槽》
javascript
Penge66611 小时前
《Go 后端开发者学 React:useState》
javascript
Penge66611 小时前
《Go 后端开发者学 React:数据渲染》
javascript
ikoala14 小时前
AI 写页面像说明书,修 Bug 像贴膏药?把这两句话写进 AGENTS.md
前端·javascript·ai编程
Penge66614 小时前
《Go 后端开发者学 TypeScript:ES Module了解》
javascript
Penge66614 小时前
《Go 后端开发者学 TypeScript:从零搭建与运行》
javascript
Penge66615 小时前
《Go 后端开发者学 TypeScript:keyof关键字》
javascript
Penge66616 小时前
《Go 后端开发者学 TypeScript:extends关键字》
javascript
张张123y16 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent