咸宁市护送服务网

Ajax基础使用详解

2026-03-24 23:41:02 浏览次数:2
详细信息

Ajax基础使用详解

什么是Ajax?

AJAX(Asynchronous JavaScript and XML,异步JavaScript和XML)是一种在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。

核心对象:XMLHttpRequest

1. 创建XMLHttpRequest对象

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

// 简单创建方式
let xhr = new XMLHttpRequest();

2. 基本请求流程

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

// 2. 配置请求
xhr.open(method, url, async);
// method: GET, POST, PUT, DELETE等
// url: 请求地址
// async: 是否异步(默认true)

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

// 4. 设置响应类型(可选)
xhr.responseType = 'json'; // 可设为 'text', 'json', 'blob', 'document'等

// 5. 发送请求
xhr.send(data); // GET请求时参数可为null或省略

// 6. 处理响应
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
        if (xhr.status === 200) {
            // 请求成功
            console.log(xhr.responseText);
        } else {
            // 请求失败
            console.error('请求失败:', xhr.status);
        }
    }
};

readyState状态值

完整示例

GET请求示例

function getData() {
    const xhr = new XMLHttpRequest();
    const url = 'https://api.example.com/data';

    xhr.open('GET', url, true);

    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status < 300) {
                // 成功
                const data = JSON.parse(xhr.responseText);
                console.log('获取的数据:', data);
                updateUI(data);
            } else {
                // 失败
                console.error('请求失败,状态码:', xhr.status);
            }
        }
    };

    xhr.onerror = function() {
        console.error('网络错误');
    };

    xhr.send();
}

POST请求示例

function postData(userData) {
    const xhr = new XMLHttpRequest();
    const url = 'https://api.example.com/users';

    xhr.open('POST', url, true);
    xhr.setRequestHeader('Content-Type', 'application/json');

    xhr.onload = function() {
        if (xhr.status >= 200 && xhr.status < 300) {
            const response = JSON.parse(xhr.responseText);
            console.log('创建成功:', response);
        } else {
            console.error('创建失败:', xhr.status);
        }
    };

    xhr.onerror = function() {
        console.error('网络错误');
    };

    // 发送JSON数据
    xhr.send(JSON.stringify(userData));
}

// 使用示例
postData({
    name: '张三',
    email: 'zhangsan@example.com'
});

使用Promise封装

function ajax(options) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        const { method, url, data, headers = {} } = options;

        xhr.open(method, url, true);

        // 设置请求头
        Object.keys(headers).forEach(key => {
            xhr.setRequestHeader(key, headers[key]);
        });

        xhr.onload = function() {
            if (xhr.status >= 200 && xhr.status < 300) {
                try {
                    const response = xhr.responseType === 'json' 
                        ? xhr.response 
                        : JSON.parse(xhr.responseText);
                    resolve(response);
                } catch (e) {
                    resolve(xhr.responseText);
                }
            } else {
                reject(new Error(`请求失败: ${xhr.status}`));
            }
        };

        xhr.onerror = function() {
            reject(new Error('网络错误'));
        };

        xhr.ontimeout = function() {
            reject(new Error('请求超时'));
        };

        // 发送请求
        if (method === 'GET' || !data) {
            xhr.send();
        } else if (data instanceof FormData) {
            xhr.send(data);
        } else {
            xhr.send(JSON.stringify(data));
        }
    });
}

// 使用示例
ajax({
    method: 'GET',
    url: 'https://api.example.com/data',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer token123'
    }
})
.then(data => console.log(data))
.catch(error => console.error(error));

处理不同响应类型

// JSON响应
xhr.responseType = 'json';
xhr.onload = function() {
    const data = xhr.response; // 直接获取JSON对象
};

// XML响应
xhr.responseType = 'document';
xhr.onload = function() {
    const xmlDoc = xhr.responseXML;
    const items = xmlDoc.getElementsByTagName('item');
};

// Blob响应(如下载文件)
xhr.responseType = 'blob';
xhr.onload = function() {
    const blob = xhr.response;
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'file.pdf';
    a.click();
    URL.revokeObjectURL(url);
};

设置超时和进度

function uploadFile(file) {
    const xhr = new XMLHttpRequest();
    const formData = new FormData();
    formData.append('file', file);

    xhr.open('POST', '/upload', true);

    // 设置超时(毫秒)
    xhr.timeout = 30000;

    // 上传进度
    xhr.upload.onprogress = function(event) {
        if (event.lengthComputable) {
            const percentComplete = (event.loaded / event.total) * 100;
            console.log(`上传进度: ${percentComplete.toFixed(2)}%`);
            updateProgressBar(percentComplete);
        }
    };

    // 下载进度
    xhr.onprogress = function(event) {
        if (event.lengthComputable) {
            const percentComplete = (event.loaded / event.total) * 100;
            console.log(`下载进度: ${percentComplete.toFixed(2)}%`);
        }
    };

    xhr.onload = function() {
        if (xhr.status === 200) {
            console.log('上传成功');
        }
    };

    xhr.ontimeout = function() {
        console.error('请求超时');
    };

    xhr.send(formData);
}

跨域请求处理

// 1. 服务器需要设置CORS头
// Access-Control-Allow-Origin: *
// Access-Control-Allow-Methods: GET, POST, PUT, DELETE
// Access-Control-Allow-Headers: Content-Type, Authorization

// 2. 带凭据的请求
xhr.withCredentials = true;

// 3. 预检请求(OPTIONS)
// 复杂请求会自动发送预检请求

实际应用示例

// 完整的API工具类
class ApiClient {
    constructor(baseUrl) {
        this.baseUrl = baseUrl;
        this.defaultHeaders = {
            'Content-Type': 'application/json',
        };
    }

    setToken(token) {
        this.defaultHeaders['Authorization'] = `Bearer ${token}`;
    }

    request(endpoint, options = {}) {
        const { method = 'GET', data, headers = {} } = options;

        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            const url = `${this.baseUrl}${endpoint}`;

            xhr.open(method, url, true);

            // 合并请求头
            const allHeaders = { ...this.defaultHeaders, ...headers };
            Object.keys(allHeaders).forEach(key => {
                xhr.setRequestHeader(key, allHeaders[key]);
            });

            xhr.onload = () => {
                if (xhr.status >= 200 && xhr.status < 300) {
                    try {
                        const response = JSON.parse(xhr.responseText);
                        resolve(response);
                    } catch (e) {
                        resolve(xhr.responseText);
                    }
                } else {
                    reject({
                        status: xhr.status,
                        message: xhr.statusText,
                        data: xhr.responseText
                    });
                }
            };

            xhr.onerror = () => reject(new Error('网络错误'));

            xhr.send(data ? JSON.stringify(data) : null);
        });
    }

    get(endpoint, params) {
        const query = params ? `?${new URLSearchParams(params)}` : '';
        return this.request(`${endpoint}${query}`);
    }

    post(endpoint, data) {
        return this.request(endpoint, { method: 'POST', data });
    }

    put(endpoint, data) {
        return this.request(endpoint, { method: 'PUT', data });
    }

    delete(endpoint) {
        return this.request(endpoint, { method: 'DELETE' });
    }
}

// 使用示例
const api = new ApiClient('https://api.example.com');

// 获取用户列表
api.get('/users')
    .then(users => console.log(users))
    .catch(error => console.error(error));

// 创建新用户
api.post('/users', { name: '李四', age: 25 })
    .then(user => console.log('创建的用户:', user));

注意事项

同源策略: Ajax请求受同源策略限制,跨域请求需要服务器支持CORS 异步性: Ajax默认是异步的,注意回调函数的执行时机 错误处理: 始终处理错误情况(网络错误、服务器错误等) 内存泄漏: 长时间未响应的请求要及时中止 兼容性: 考虑旧版浏览器兼容性 安全性: 避免敏感信息泄露,验证服务器响应

中止请求

const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data', true);
xhr.send();

// 中止请求
xhr.abort();

// 检查是否已中止
if (xhr.readyState !== 4) {
    console.log('请求已中止');
}

现代替代方案

虽然XMLHttpRequest是基础,但现代开发中更常用:

Ajax是现代Web应用的基础,理解其原理和用法对于前端开发至关重要。

相关推荐