欢迎光临优选殡葬网
详情描述

异步请求AJAX原理

一、AJAX核心原理

AJAX(Asynchronous JavaScript and XML) 通过在后台与服务器交换少量数据,实现网页的异步更新,避免整个页面刷新。

工作原理: 创建XMLHttpRequest对象:浏览器内置对象,用于与服务器交互 配置请求参数:设置请求方法、URL、异步标志等 发送请求:向服务器发送HTTP请求 监听状态变化:通过事件监听请求状态 处理响应:服务器返回数据后进行处理
// 原生AJAX请求流程
用户界面 → JavaScript调用XMLHttpRequest → HTTP请求 → 服务器
服务器 → XML/JSON数据 → XMLHttpRequest回调函数 → 更新页面

二、原生AJAX详解

1. 创建XMLHttpRequest对象

// 兼容性写法
function createXHR() {
    if (window.XMLHttpRequest) {
        // 现代浏览器
        return new XMLHttpRequest();
    } else {
        // 旧版IE
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
}

var xhr = createXHR();

2. 完整请求示例

// 1. 创建对象
var xhr = new XMLHttpRequest();

// 2. 配置请求
xhr.open('GET', 'https://api.example.com/data', true); // true表示异步

// 3. 设置请求头(可选)
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer token123');

// 4. 监听状态变化
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) { // 请求完成
        if (xhr.status >= 200 && xhr.status < 300) { // 成功状态码
            var data = JSON.parse(xhr.responseText);
            console.log('成功:', data);
        } else {
            console.error('请求失败:', xhr.status);
        }
    }
};

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

// POST请求示例
xhr.open('POST', 'https://api.example.com/data', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('name=John&age=25');

3. readyState状态码

0: 未初始化 - XMLHttpRequest对象已创建
1: 已打开 - open()方法已调用
2: 已发送 - send()方法已调用
3: 接收中 - 正在接收响应数据
4: 完成 - 响应数据接收完成

4. 事件监听方式(推荐)

var xhr = new XMLHttpRequest();

// 进度事件
xhr.onloadstart = function() { console.log('开始加载'); };
xhr.onprogress = function(event) {
    if (event.lengthComputable) {
        var percent = (event.loaded / event.total) * 100;
        console.log('加载进度:', percent + '%');
    }
};

// 加载完成
xhr.onload = function() {
    if (xhr.status === 200) {
        console.log('请求成功:', xhr.response);
    }
};

// 错误处理
xhr.onerror = function() {
    console.error('网络请求失败');
};

// 超时处理
xhr.timeout = 5000; // 5秒超时
xhr.ontimeout = function() {
    console.error('请求超时');
};

xhr.open('GET', 'api/data', true);
xhr.send();

三、jQuery $.ajax使用详解

1. 基本语法

$.ajax({
    url: 'api/data',           // 请求地址
    type: 'GET',               // 请求方法 GET/POST/PUT/DELETE
    dataType: 'json',          // 预期返回数据类型
    data: {                    // 发送到服务器的数据
        id: 1,
        name: 'John'
    },
    success: function(data) {   // 请求成功回调
        console.log('成功:', data);
    },
    error: function(xhr, status, error) { // 请求失败回调
        console.error('失败:', error);
    },
    complete: function(xhr, status) {     // 请求完成回调(无论成功失败)
        console.log('请求完成');
    }
});

2. 常用配置选项

$.ajax({
    url: 'api/data',
    type: 'POST',

    // 数据相关
    data: JSON.stringify({user: 'John'}), // 可发送字符串
    contentType: 'application/json',      // 发送数据的类型
    dataType: 'json',                     // 预期服务器返回类型

    // 请求头设置
    headers: {
        'Authorization': 'Bearer token123',
        'Custom-Header': 'value'
    },

    // 异步控制
    async: true,                          // 默认true(异步)
    timeout: 3000,                        // 超时时间(毫秒)

    // 回调函数
    beforeSend: function(xhr) {
        // 发送前可修改请求头
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        console.log('正在发送请求...');
    },

    success: function(data, status, xhr) {
        console.log('请求成功', data);
    },

    error: function(xhr, status, error) {
        console.error('状态码:', xhr.status);
        console.error('错误信息:', error);
    },

    complete: function(xhr, status) {
        console.log('请求完成,状态:', status);
    }
});

3. 快捷方法

// GET请求
$.get('api/data', {id: 1}, function(data) {
    console.log(data);
}, 'json');

// POST请求
$.post('api/save', {name: 'John'}, function(data) {
    console.log(data);
});

// 加载HTML内容到元素
$('#result').load('partials/content.html #section');

// 获取JSON数据
$.getJSON('api/data.json', function(data) {
    console.log(data);
});

4. Promise风格调用(jQuery 1.5+)

// 链式调用
$.ajax('api/data')
    .done(function(data) {
        console.log('成功:', data);
    })
    .fail(function(xhr, status, error) {
        console.error('失败:', error);
    })
    .always(function() {
        console.log('请求完成');
    });

// 多个请求
$.when(
    $.ajax('api/users'),
    $.ajax('api/products')
).then(function(usersResponse, productsResponse) {
    var users = usersResponse[0];
    var products = productsResponse[0];
    console.log('所有请求完成', users, products);
});

四、实际应用示例

1. 文件上传进度

// 使用FormData上传文件
var formData = new FormData();
formData.append('file', fileInput.files[0]);

$.ajax({
    url: 'api/upload',
    type: 'POST',
    data: formData,
    processData: false,  // 不处理数据
    contentType: false,  // 不设置内容类型

    // 上传进度
    xhr: function() {
        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener('progress', function(e) {
            if (e.lengthComputable) {
                var percent = Math.round((e.loaded / e.total) * 100);
                $('#progress-bar').width(percent + '%');
            }
        });
        return xhr;
    },

    success: function(response) {
        console.log('上传成功:', response);
    }
});

2. 带取消功能的请求

// 原生AJAX
var xhr = new XMLHttpRequest();
xhr.open('GET', 'api/long-running', true);
xhr.send();

// 取消请求
document.getElementById('cancel-btn').addEventListener('click', function() {
    xhr.abort();
    console.log('请求已取消');
});

// jQuery
var jqXHR = $.ajax('api/data');
jqXHR.abort(); // 取消请求

3. 错误统一处理

// 设置全局AJAX配置
$.ajaxSetup({
    timeout: 5000,
    error: function(xhr, status, error) {
        switch(xhr.status) {
            case 401:
                alert('请先登录');
                window.location.href = '/login';
                break;
            case 403:
                alert('没有权限');
                break;
            case 404:
                alert('资源不存在');
                break;
            case 500:
                alert('服务器错误');
                break;
            default:
                console.error('请求错误:', error);
        }
    }
});

// 发送请求(自动应用全局配置)
$.ajax({
    url: 'api/data',
    success: function(data) {
        // 处理数据
    }
});

五、最佳实践和注意事项

1. 安全性考虑

  • 使用HTTPS传输敏感数据
  • 验证和过滤用户输入
  • 设置CSRF令牌
  • 实施CORS策略

2. 性能优化

// 缓存控制
$.ajax({
    url: 'api/data',
    cache: false, // 禁止缓存
    // 或
    headers: {
        'Cache-Control': 'no-cache'
    }
});

// 节流控制
var requestTimer;
function search(query) {
    clearTimeout(requestTimer);
    requestTimer = setTimeout(function() {
        $.get('api/search', {q: query}, function(data) {
            // 显示结果
        });
    }, 300); // 300ms延迟
}

3. 兼容性处理

// 特征检测
if (window.XMLHttpRequest) {
    // 支持现代AJAX
    var xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
    // IE6及以下
    try {
        var xhr = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
        var xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
}

// 回退方案
function makeRequest(url, success, error) {
    if (window.XMLHttpRequest) {
        // 使用AJAX
        $.ajax({
            url: url,
            success: success,
            error: error
        });
    } else {
        // 使用JSONP或其他替代方案
        var script = document.createElement('script');
        script.src = url + '?callback=handleResponse';
        document.head.appendChild(script);
    }
}

六、现代替代方案

虽然AJAX仍然有效,但现代开发更推荐:

Fetch API:更现代、更强大的原生API

fetch('api/data')
 .then(response => response.json())
 .then(data => console.log(data))
 .catch(error => console.error(error));

Axios:流行的HTTP客户端库

axios.get('api/data')
 .then(response => console.log(response.data))
 .catch(error => console.error(error));

掌握AJAX原理对于理解现代Web开发至关重要,虽然现在有更多现代工具,但理解底层原理有助于更好地解决问题和进行性能优化。

相关帖子
三明市殡仪服务公司,殡葬服务车出租,全城服务
三明市殡仪服务公司,殡葬服务车出租,全城服务
三明市高效获客助手#网站制作设计服务公司,小程序开发
三明市高效获客助手#网站制作设计服务公司,小程序开发
三明市白事殡葬一条龙服务-入殓化妆,一流的质量
三明市白事殡葬一条龙服务-入殓化妆,一流的质量
关于家庭安全,定期检查水电燃气设施的具体项目和周期应该是怎样的?
关于家庭安全,定期检查水电燃气设施的具体项目和周期应该是怎样的?
如何帮助孩子在课后服务时段与不同年级的同学进行良性的互动和共同学习?
如何帮助孩子在课后服务时段与不同年级的同学进行良性的互动和共同学习?
社区推广的节水节电节气倡议与措施对家庭生活有哪些益处?
社区推广的节水节电节气倡议与措施对家庭生活有哪些益处?
六盘水安卓app开发#网站定制开发公司,多年专业建站经验
六盘水安卓app开发#网站定制开发公司,多年专业建站经验
河池市丧葬一条龙服务电话,丧事办理,全城服务
河池市丧葬一条龙服务电话,丧事办理,全城服务
廊坊市殡葬服务正规公司|白事服务,殡葬追悼会策划
廊坊市殡葬服务正规公司|白事服务,殡葬追悼会策划
写字楼门店房抵押贷款可以用于装修吗?装修用途条件与流程
写字楼门店房抵押贷款可以用于装修吗?装修用途条件与流程
四平市专业网站建设优化-erp系统开发,多年建站经验
四平市专业网站建设优化-erp系统开发,多年建站经验
岳阳市殡仪服务流程-出租冰棺服务,快速上门
岳阳市殡仪服务流程-出租冰棺服务,快速上门
玉树殡葬服务一站式办理-丧礼服务,个性化服务
玉树殡葬服务一站式办理-丧礼服务,个性化服务
许昌市app开发#网站建设制作,专业建站公司
许昌市app开发#网站建设制作,专业建站公司
达州市网站开发正规公司-苹果系统app开发,服务可靠
达州市网站开发正规公司-苹果系统app开发,服务可靠
榆林市殡葬一条龙公司电话,白事殡葬一条龙服务,安全可靠
榆林市殡葬一条龙公司电话,白事殡葬一条龙服务,安全可靠
当遇到劳动合同纠纷时,除了劳动仲裁,还有哪些高效便捷的解决途径?
当遇到劳动合同纠纷时,除了劳动仲裁,还有哪些高效便捷的解决途径?
小区房子抵押贷款和别墅抵押贷款有什么区别?这五点差异必须了解
小区房子抵押贷款和别墅抵押贷款有什么区别?这五点差异必须了解
诸暨市殡葬服务电话|殡仪服务,丧葬追思会服务
诸暨市殡葬服务电话|殡仪服务,丧葬追思会服务
洛阳市短视频运营推广#网站定制开发,收费标准
洛阳市短视频运营推广#网站定制开发,收费标准
过桥垫资评估费怎么收?评估费收费标准与计算方式详细说明
过桥垫资评估费怎么收?评估费收费标准与计算方式详细说明