知识篇 -- JS网络请求:数据交互

Ray Shine 2024/2/17 JavaScript进阶知识网络请求HTTP

在现代Web应用中,前端与后端的数据交互是不可或缺的一部分。JavaScript提供了多种机制来实现网络请求,从传统的 XMLHttpRequest 到现代的 Fetch API,再到流行的第三方库 Axios。理解这些网络请求方式的特点、用法和最佳实践,是构建动态、数据驱动型Web应用的关键。

# 一、XMLHttpRequest (XHR):传统请求方式 传统

XMLHttpRequest 是一个JavaScript对象,用于在后台与服务器交换数据。它是Ajax(Asynchronous JavaScript and XML)技术的核心。

  • 特点
    • 老牌:兼容性好,几乎所有浏览器都支持。
    • 事件驱动:通过监听不同的事件(如 onload, onerror, onprogress)来处理请求的各个阶段。
    • 配置复杂:API相对底层,需要手动设置请求头、处理状态码等。
    • 回调地狱:在处理多个串联请求时,容易陷入回调地狱。
  • 基本用法
    const xhr = new XMLHttpRequest();
    xhr.open("GET", "https://api.example.com/data", true); // true表示异步
    xhr.timeout = 2000; // 设置超时时间
    
    xhr.onload = function() {
        if (xhr.status >= 200 && xhr.status < 300) {
            console.log("请求成功:", JSON.parse(xhr.responseText));
        } else {
            console.error("请求失败:", xhr.status, xhr.statusText);
        }
    };
    
    xhr.onerror = function() {
        console.error("网络错误或请求被阻止。");
    };
    
    xhr.ontimeout = function() {
        console.error("请求超时。");
    };
    
    xhr.send(); // 发送请求
    
  • 发送POST请求
    xhr.open("POST", "https://api.example.com/submit", true);
    xhr.setRequestHeader("Content-Type", "application/json"); // 设置请求头
    xhr.send(JSON.stringify({ key: "value" })); // 发送JSON数据
    

# 二、Fetch API:现代Web请求标准 (ES6新增) 现代

Fetch API 提供了 XMLHttpRequest 的所有功能,但设计更简洁、更强大,并且基于Promise,使得异步请求的处理更加优雅。

  • 特点
    • 基于Promise:天然支持 async/await,解决了回调地狱问题。
    • API简洁:更符合现代JavaScript的编程风格。
    • 流式处理:支持流式读取响应体。
    • 默认不发送Cookie:需要手动设置 credentials: 'include'
    • 错误处理fetch 只有在网络错误或请求被阻止时才 reject Promise。对于HTTP错误状态码(如404, 500),Promise仍然会 resolve,但 response.ok 会是 false
  • 基本用法
    fetch("https://api.example.com/data")
        .then(response => {
            if (!response.ok) { // 检查HTTP状态码
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json(); // 解析JSON响应体
        })
        .then(data => {
            console.log("请求成功:", data);
        })
        .catch(error => {
            console.error("请求失败:", error);
        });
    
  • 发送POST请求
    fetch("https://api.example.com/submit", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({ key: "value" })
    })
    .then(response => response.json())
    .then(data => console.log("提交成功:", data))
    .catch(error => console.error("提交失败:", error));
    
  • 使用 async/await
    async function fetchDataAsync() {
        try {
            const response = await fetch("https://api.example.com/data");
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            const data = await response.json();
            console.log("请求成功:", data);
        } catch (error) {
            console.error("请求失败:", error);
        }
    }
    fetchDataAsync();
    

# 三、Axios:流行的第三方HTTP客户端 第三方库

Axios 是一个基于Promise的HTTP客户端,可以在浏览器和Node.js环境中使用。它在 XMLHttpRequesthttp 模块的基础上进行了封装,提供了更强大的功能和更友好的API。

  • 特点
    • 基于Promise:支持 async/await
    • 自动转换JSON数据:请求和响应数据会自动进行JSON转换。
    • 拦截器:支持请求和响应拦截器,方便统一处理请求头、错误等。
    • 取消请求:支持取消请求。
    • 客户端防御XSRF:提供了一些安全特性。
    • 兼容性:支持旧版浏览器。
  • 安装npm install axiosyarn add axios
  • 基本用法
    // GET请求
    axios.get("https://api.example.com/data")
        .then(response => {
            console.log("请求成功:", response.data); // response.data直接就是解析后的JSON
        })
        .catch(error => {
            console.error("请求失败:", error);
        });
    
    // POST请求
    axios.post("https://api.example.com/submit", {
        key: "value" // Axios会自动将其转换为JSON
    })
    .then(response => {
        console.log("提交成功:", response.data);
    })
    .catch(error => {
        console.error("提交失败:", error);
    });
    
  • 使用 async/await
    async function fetchDataAxios() {
        try {
            const response = await axios.get("https://api.example.com/data");
            console.log("请求成功:", response.data);
        } catch (error) {
            console.error("请求失败:", error);
            if (error.response) {
                // 请求已发出,但服务器响应的状态码不在 2xx 范围内
                console.error("响应数据:", error.response.data);
                console.error("响应状态:", error.response.status);
                console.error("响应头:", error.response.headers);
            } else if (error.request) {
                // 请求已发出,但没有收到响应
                console.error("没有收到响应:", error.request);
            } else {
                // 在设置请求时发生了其他错误
                console.error("其他错误:", error.message);
            }
        }
    }
    fetchDataAxios();
    
  • 拦截器示例
    // 请求拦截器
    axios.interceptors.request.use(config => {
        // 在发送请求之前做些什么
        config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
        return config;
    }, error => {
        // 对请求错误做些什么
        return Promise.reject(error);
    });
    
    // 响应拦截器
    axios.interceptors.response.use(response => {
        // 对响应数据做些什么
        return response;
    }, error => {
        // 对响应错误做些什么
        if (error.response.status === 401) {
            // 处理认证失败
            console.log("认证失败,请重新登录。");
        }
        return Promise.reject(error);
    });
    

# 四、总结

JavaScript网络请求是前端开发中与后端交互的桥梁。从传统的 XMLHttpRequest 到现代的 Fetch API,再到功能强大的 Axios 库,每种方式都有其独特的优势。在现代项目中,Fetch APIAxios 是主流选择,它们提供了基于Promise的异步处理能力,使得网络请求的代码更加简洁、可读和易于维护。合理选择和运用这些工具,能够帮助你高效地构建数据驱动的Web应用。

最后更新时间: 2025/11/20 22:59:30
ON THIS PAGE