AJAX技术详解:前后端数据交互基础

在Web开发中,实现页面的局部更新和无刷新数据交互是提升用户体验的关键。AJAX(Asynchronous JavaScript and XML)作为一项核心技术,让这种交互成为可能。本文将深入讲解AJAX的原理、应用场景及实现方式。

一、AJAX基础概念

1.1 什么是AJAX

  • AJAX全称:Asynchronous JavaScript and XML(异步的JavaScript和XML)
  • 核心作用:实现浏览器和服务器的异步数据交互
  • 特点:可以在不刷新整个页面的情况下,与服务器交换数据并更新部分网页内容

XMLHttpRequest实例的创建与使用

// 1. 标准创建方式
const xhr = new XMLHttpRequest();

// 2. 兼容性写法(适配IE5/6)
function createXHR() {
    if (typeof XMLHttpRequest !== "undefined") {
        return new XMLHttpRequest();
    } else if (typeof ActiveXObject !== "undefined") {
        // IE6及以下
        if (typeof arguments.callee.activeXString !== "string") {
            const versions = [
                "MSXML2.XMLHttp.6.0",
                "MSXML2.XMLHttp.3.0",
                "MSXML2.XMLHttp"
            ];
            for (let i = 0; i < versions.length; i++) {
                try {
                    new ActiveXObject(versions[i]);
                    arguments.callee.activeXString = versions[i];
                    break;
                } catch(ex) {
                    // 跳过
                }
            }
        }
        return new ActiveXObject(arguments.callee.activeXString);
    } else {
        throw new Error("No XHR object available");
    }
}

1.2 同步与异步的区别

同步:

  • 代码按顺序执行
  • 前一个任务完成后才能执行后一个任务
  • 可能造成页面阻塞

异步:

  • 多个任务可以同时执行
  • 任务之间互不影响
  • 提高页面性能和用户体验
// 同步示例
console.log('开始');
alert('同步操作');
console.log('结束');

// 异步示例
console.log('开始');
setTimeout(() => {
    console.log('异步操作');
}, 1000);
console.log('结束');

二、AJAX状态码详解

2.1 readyState状态码

XMLHttpRequest对象的readyState属性表示请求/响应过程的当前活动阶段:

const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    switch(xhr.readyState) {
        case 0: // UNSENT
            console.log('尚未调用open()方法');
            break;
        case 1: // OPENED
            console.log('已调用open()方法');
            break;
        case 2: // HEADERS_RECEIVED
            console.log('已接收响应头');
            break;
        case 3: // LOADING
            console.log('正在接收响应体');
            break;
        case 4: // DONE
            console.log('请求完成');
            break;
    }
};

2.2 HTTP状态码

常见的HTTP状态码及其含义:

  • 2xx 成功响应
    • 200:请求成功
    • 201:创建成功
  • 3xx 重定向
    • 301:永久重定向
    • 302:临时重定向
  • 4xx 客户端错误
    • 400:请求语法错误
    • 404:资源不存在
  • 5xx 服务器错误
    • 500:服务器内部错误

2.3 XHR对象的属性

// 1. readyState - 请求/响应过程的当前活动阶段
xhr.readyState  
// 0: 未初始化。尚未调用open()方法
// 1: 启动。已经调用open()方法,但未调用send()方法
// 2: 发送。已经调用send()方法,但尚未接收到响应
// 3: 接收。已经接收到部分响应数据
// 4: 完成。已经接收到全部响应数据

// 2. status - HTTP状态码
xhr.status  // 如:200, 404, 500等

// 3. statusText - HTTP状态说明
xhr.statusText  // 如:"OK", "Not Found"等

// 4. responseType - 响应数据类型
xhr.responseType  // "text", "json", "blob", "arraybuffer"等

// 5. response - 响应内容
xhr.response

// 6. timeout - 超时时间设置(毫秒)
xhr.timeout = 3000;

   2.4 核心方法使用

// 1. open() - 初始化请求
xhr.open("GET", "url", true);  // method, url, async
// 第三个参数true表示异步请求,false表示同步请求

// 2. send() - 发送请求
xhr.send(null);  // GET请求
xhr.send(data);  // POST请求发送数据

// 3. setRequestHeader() - 设置请求头
xhr.setRequestHeader("Content-Type", "application/json");

// 4. abort() - 终止请求
xhr.abort();

AJAX请求默认是异步的,但确实可以配置为同步。这两种模式各有适用场景

异步请求(默认)

适用场景:

  • 大多数情况下应该使用异步请求
  • 需要保持用户界面响应性的情况
  • 执行后台操作而不阻塞用户交互
  • 多个并行请求需要同时进行
  • 长时间运行的操作(如数据上传、大量数据处理)

优点:

  • 不会阻塞用户界面
  • 提供更好的用户体验
  • 允许用户继续与页面交互
  • 可以同时处理多个请求

同步请求(特殊情况)

适用场景:

  • 当后续代码严格依赖于请求结果才能继续执行
  • 需要确保按特定顺序执行的操作
  • 加载关键配置数据,必须先完成才能继续
  • 简单的脚本或原型开发,不关注用户体验
  • 在注销或页面卸载前需要保证数据已发送到服务器

注意事项:

  • 同步请求会完全阻塞浏览器界面
  • 现代浏览器已经开始不推荐或禁用同步请求
  • 会导致糟糕的用户体验,用户界面会冻结直到请求完成

最佳实践是尽可能使用异步请求,结合回调函数、Promise或async/await来处理请求完成后的逻辑,而不是使用同步请求。大多数现代浏览器已经不再推荐使用同步AJAX请求,并在控制台中发出警告。

2.5 事件处理

// 1. onreadystatechange - 请求状态变化事件
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
        if (xhr.status === 200) {
            console.log(xhr.responseText);
        }
    }
};

// 2. 其他常用事件
xhr.onload = function() {
    // 请求完成时触发
};

xhr.onerror = function() {
    // 请求错误时触发
};

xhr.ontimeout = function() {
    // 请求超时时触发
};

xhr.onabort = function() {
    // 请求终止时触发
};

xhr.onprogress = function(event) {
    // 接收数据过程中周期性触发
    if (event.lengthComputable) {
        const percentComplete = (event.loaded / event.total) * 100;
        console.log(percentComplete + '% completed');
    }
};

  2.6 完整使用示例

function ajax(options) {
    const xhr = new XMLHttpRequest();
    
    // 设置超时
    xhr.timeout = options.timeout || 3000;
    
    // 监听状态变化
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
                options.success && options.success(xhr.responseText);
            } else {
                options.error && options.error(xhr.status);
            }
        }
    };
    
    // 监听错误
    xhr.onerror = function() {
        options.error && options.error();
    };
    
    // 监听超时
    xhr.ontimeout = function() {
        options.timeout && options.timeout();
    };
    
    // 处理请求参数
    let url = options.url;
    if (options.method.toUpperCase() === 'GET' && options.data) {
        url += '?' + Object.entries(options.data)
            .map(([key, value]) => `${key}=${value}`)
            .join('&');
    }
    
    // 初始化请求
    xhr.open(options.method, url, true);
    
    // 设置请求头
    if (options.headers) {
        Object.entries(options.headers).forEach(([key, value]) => {
            xhr.setRequestHeader(key, value);
        });
    }
    
    // 发送请求
    if (options.method.toUpperCase() === 'POST') {
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send(JSON.stringify(options.data));
    } else {
        xhr.send();
    }
}

// 使用示例
ajax({
    url: 'https://api.example.com/data',
    method: 'POST',
    data: {
        name: 'test',
        age: 18
    },
    headers: {
        'Authorization': 'Bearer token'
    },
    success: function(res) {
        console.log('请求成功:', res);
    },
    error: function(status) {
        console.log('请求失败:', status);
    },
    timeout: function() {
        console.log('请求超时');
    }
});

三、GET与POST请求详解

3.1 GET请求特点

  • 用于获取数据

                用于从服务器获取(拿取)数据

  • 参数通过URL传递

                在浏览器地址栏输入URL回车时,默认使用GET请求(通常用于查询操作)

  • 有缓存

                通过时间戳解决该问题

  • 传数据量较小
const xhr = new XMLHttpRequest();
xhr.open('GET', 'api/data?id=123&name=test', true);
// 解决GET请求缓存问题
xhr.open('GET', `api/data?t=${new Date().getTime()}`, true);
xhr.send();

  基本格式说明:

  1. ? - 问号后面开始是 URL 参数
  1. 参数=值 - 每个参数都是 "参数名=参数值" 的格式
  1. & - 使用 & 符号分隔多个参数
https://example.com/path?参数1=值1&参数2=值2&参数3=值3

3.2 POST请求特点

  • 用于提交数据
  • 参数通过请求体传递

                用于向服务器提交(发送)数据,多与表单提交场景搭配,通常用于创建或更新操作

  • 无缓存
  • 可传输大量数据
  • 相对更安全
const xhr = new XMLHttpRequest();
xhr.open('POST', 'api/data', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({id: 123, name: 'test'}));

AJAX请求主要使用的是HTTP请求方法,HTTP协议定义的标准请求方法只有9种

GET、POST、PUT、DELETE、HEAD、OPTIONS、PATCH、CONNECT、TRACE

比较常见的 6 种请求方式:

  • GET - 用于从服务器获取数据,参数通常附加在URL后面
  • POST - 用于向服务器发送数据以创建或更新资源,数据包含在请求体中
  • PUT - 用于更新服务器上的现有资源,发送完整的资源数据
  • DELETE - 用于删除服务器上的指定资源
  • PATCH - 用于对资源进行部分更新,只发送需要修改的部分
  • HEAD - 类似于GET请求但只请求头信息,不返回响应体

具体用什么请求方式,由后端决定,后端会写一个接口文档给前端

四、接口(API)概念

接口是只返回数据而没有界面的URL地址,英文叫api(Application Programming Interface)

输入网址能在页面上显示数据的都为接口地址,简称接口

        接口链接示例:   https://jsonplaceholder.typicode.com/users 

复制到浏览器地址栏并回车即可查看接口数据

五、API接口文档示例

一个标准的接口文档应有的内容如下

基本信息说明
接口名称用户登录
接口描述用户通过账号密码进行登录认证
接口URL/api/v1/user/login
请求方式POST
开发者张三
创建时间2024-02-22
更新时间2024-02-22
请求头(Headers)是否必须示例值说明
Content-Typeapplication/json请求类型
AuthorizationBearer eyJhbGciOi...登录凭证
x-client-idweb客户端标识
请求参数(Request Body)类型是否必须示例值说明
usernamestringzhangsan用户名
passwordstringmd5(123456)MD5加密后的密码
captchastringa1b2c验证码
rememberbooleantrue是否记住登录
响应参数(Response)类型说明示例值
codenumber响应码200
messagestring响应描述"登录成功"
data.userIdstring用户ID"12345"
data.usernamestring用户名称"张三"
data.tokenstring访问令牌"eyJhbGciOi..."
data.permissionsarray权限列表["user:read"]
响应状态码说明处理建议
200请求成功-
400参数错误检查请求参数
401未授权检查登录状态
403权限不足检查用户权限
500服务器错误联系后端开发
5.1 请求示例

后端接口需要的参数

{
    "username": "zhangsan",
    "password": "e10adc3949ba59abbe56e057f20f883e",
    "captcha": "a1b2c",
    "remember": true
}
5.2 响应示例 

后端返回的数据

{
    "code": 200,
    "message": "登录成功",
    "data": {
        "userId": "12345",
        "username": "张三",
        "token": "eyJhbGciOi...",
        "permissions": ["user:read", "user:write"]
    }
}

   5.2 失败响应示例

接口因为某些原因没请求成功

{
    "code": 401,
    "message": "用户名或密码错误",
    "data": null
}
补充说明内容
请求限制接口调用频率:10次/分钟
安全要求密码需MD5加密,必须使用HTTPS
特殊说明Token有效期为2小时
修改记录
修改人张三
修改时间2024-02-22
修改内容创建接口文档

AJAX与接口文档知识总结

核心知识点回顾

  1. AJAX三大核心
  • XMLHttpRequest对象的创建和使用
  • GET/POST请求的区别和应用场景
  • 异步处理机制和状态码判断
  1. 接口规范要点
  • 标准的接口文档结构(基本信息、请求参数、响应格式)
  • 接口安全性考虑(请求头、鉴权方式)
  • 错误处理机制

实际应用建议

  1. 开发实践
  • AJAX请求建议封装统一处理函数
  • 善用Promise处理异步请求
  • 合理使用GET/POST:查询用GET,提交用POST
  1. 文档规范
  • 使用统一的文档模板
  • 保持文档及时更新
  • 示例代码必须完整可用

重点注意事项

  1. AJAX使用注意
  • 处理好跨域问题
  • 注意GET请求的缓存问题
  • 异常处理不可遗漏
  1. 接口文档维护
  • 参数说明要清晰完整
  • 及时更新接口变更
  • 做好版本控制

学习建议

  • 多写demo加深理解
  • 实际项目中注意积累经验
  • 推荐使用成熟的请求库(如Axios)
  • 熟练使用接口文档工具(如Swagger)

通过掌握AJAX和规范的接口文档写法,我们能更好地进行前后端协作,提高开发效率。在实际工作中,应当注重实践和积累,不断提升自己的专业能力。

从原生AJAX到Axios

知识衔接说明

  1. 学习路径
  • 学习原生AJAX是为了理解底层原理
  • Axios是在AJAX基础上的封装优化
  • 实际开发中推荐使用 Axios
  1. Axios的优势
  • 更简洁的API设计
  • 自动转换JSON数据
  • 客户端支持防御XSRF
  • 请求和响应的拦截器
  • 更好的异常处理机制

官网说明

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF
实际开发建议
// 原生AJAX写法(学习理解原理)
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/users');
xhr.onreadystatechange = function() {
    if(xhr.readyState === 4 && xhr.status === 200) {
        console.log(xhr.responseText);
    }
};
xhr.send();

// Axios写法(实际开发使用)
axios.get('/api/users')
    .then(response => console.log(response.data))
    .catch(error => console.log(error));

学习建议

  • 先掌握AJAX原理,理解异步请求的本质
  • 再学习Axios,提高开发效率
  • 实际项目中使用Axios,遇到问题能追溯到AJAX层面解决

记住:学习原生AJAX是为了理解原理,而在实际工作中,Axios等成熟的HTTP客户端库才是首选。这样既掌握了基础原理,又能提高开发效率。

博主另一篇文章有对 axios 请求库的介绍:感兴趣可以看看 

Axios 实战:拦截器、封装与工作中的关键应用

前后端是如何配合的 博主另一篇文档

前后端联调

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端切图仔001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值