JavaScript原生AJAX技术详解:XMLHttpRequest与Fetch API的全面解析

文章目录

JavaScript原生AJAX技术详解:XMLHttpRequest与Fetch API的全面解析

一、原生AJAX概述

AJAX(Asynchronous JavaScript and XML)是一种在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。JavaScript原生实现AJAX的方式主要有两种:

  • XMLHttpRequest(XHR):传统的AJAX实现方式,自IE5开始支持,是早期Web开发的核心异步请求方案。
  • Fetch API:ES6引入的现代异步请求接口,基于Promise设计,语法更简洁,是XHR的替代方案。

二、两种原生AJAX方式的详细介绍

1. XMLHttpRequest(XHR)

XMLHttpRequest是最早的原生AJAX实现,通过创建XMLHttpRequest对象发起HTTP请求,支持同步/异步操作,可处理多种数据格式(XML、JSON、文本等)。

基本使用步骤:
  1. 创建XMLHttpRequest实例
  2. 配置请求(方法、URL、同步/异步)
  3. 注册事件监听(如onreadystatechange处理响应)
  4. 设置请求头(可选,如Content-Type
  5. 发送请求(send()
代码示例(GET请求):
// 创建XHR实例
const xhr = new XMLHttpRequest();

// 配置请求:方法、URL、是否异步
xhr.open('GET', 'https://api.example.com/data', true);

// 设置请求头(可选)
xhr.setRequestHeader('Accept', 'application/json');

// 监听状态变化
xhr.onreadystatechange = function() {
  // readyState=4表示请求完成,status=200表示成功
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      try {
        const data = JSON.parse(xhr.responseText);
        console.log('请求成功:', data);
      } catch (e) {
        console.error('解析响应失败:', e);
      }
    } else {
      console.error('请求失败,状态码:', xhr.status);
    }
  }
};

// 发送请求
xhr.send();
代码示例(POST请求):
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/submit', true);

// 设置POST请求的Content-Type
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    if (xhr.status >= 200 && xhr.status < 300) {
      console.log('提交成功:', xhr.responseText);
    } else {
      console.error('提交失败:', xhr.statusText);
    }
  }
};

// 发送JSON数据
const postData = { name: '张三', age: 25 };
xhr.send(JSON.stringify(postData));

2. Fetch API

Fetch API是ES6推出的现代异步请求接口,基于Promise设计,语法更简洁,支持链式调用和async/await,更符合现代JavaScript开发习惯。

基本使用特点:
  • 默认返回Promise对象,避免回调地狱
  • 响应处理需显式调用response.json()/response.text()等方法
  • 仅在网络错误时才会reject,HTTP错误状态(如404、500)不会触发reject
代码示例(GET请求,Promise链式):
fetch('https://api.example.com/data', {
  method: 'GET',
  headers: {
    'Accept': 'application/json'
  }
})
  // 第一步:检查响应状态
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP错误,状态码:${response.status}`);
    }
    // 第二步:解析响应为JSON
    return response.json();
  })
  // 第三步:处理数据
  .then(data => {
    console.log('请求成功:', data);
  })
  // 捕获错误(网络错误或自定义错误)
  .catch(error => {
    console.error('请求失败:', error.message);
  });
代码示例(POST请求,async/await):
async function submitData() {
  try {
    const response = await fetch('https://api.example.com/submit', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ name: '张三', age: 25 }) // 请求体
    });

    if (!response.ok) {
      throw new Error(`提交失败,状态码:${response.status}`);
    }

    const result = await response.json();
    console.log('提交成功:', result);
  } catch (error) {
    console.error('请求错误:', error.message);
  }
}

// 调用函数
submitData();

三、两种方式的优缺点对比

特性XMLHttpRequestFetch API
语法基于事件回调,较繁琐基于Promise,支持链式调用和async/await
兼容性兼容所有浏览器(包括IE5+)IE不支持,需使用polyfill(如whatwg-fetch)
同步请求支持(open()第三个参数设为false)不支持(仅异步)
错误处理通过status判断,需在onreadystatechange中处理仅网络错误reject,HTTP错误需手动判断response.ok
请求中断支持abort()方法支持AbortController中断
默认行为自动携带cookie默认不携带cookie,需设置credentials: 'include'
进度监听支持progress事件监听上传/下载进度需通过ReadableStream实现,较复杂
响应类型处理需手动解析responseText/responseXML提供json()/text()/blob()等方法自动解析

四、使用注意事项

  1. 跨域问题
    无论是XHR还是Fetch,都受浏览器同源策略限制。跨域请求需服务器配置CORS(Access-Control-Allow-Origin等响应头),否则会触发跨域错误。

  2. 数据解析

    • XHR需手动通过JSON.parse()解析JSON响应,注意处理解析错误。
    • Fetch的response.json()返回Promise,需二次thenawait,且仅适用于JSON格式。
  3. 错误处理

    • XHR需同时判断readyState === 4status(200-299为成功)。
    • Fetch需显式检查response.okresponse.ok等价于status >= 200 && status < 300),否则需手动抛出错误。
  4. 兼容性处理

    • 若需支持IE,优先使用XHR;使用Fetch需引入polyfill(如whatwg-fetch)。
    • 现代浏览器(Chrome、Firefox、Edge等)对Fetch支持良好。
  5. 安全性

    • 避免在请求中暴露敏感信息(如密钥),建议通过HTTPS传输。
    • 处理响应数据时注意防XSS攻击(尤其是文本内容直接插入DOM时)。
  6. 请求中断

    • XHR可通过xhr.abort()中断请求。
  • Fetch需配合AbortController
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(response => { /* 处理响应 */ });
// 中断请求
controller.abort();

五、总结

  • XMLHttpRequest:适合需要兼容旧浏览器(如IE)、需同步请求或精细控制进度的场景,但其回调式语法较繁琐,易导致代码混乱。
  • Fetch API:现代项目的首选方案,基于Promise的设计更符合ES规范,配合async/await可写出简洁清晰的异步代码,缺点是兼容性有限且错误处理需手动实现。

在实际开发中,若目标浏览器为现代浏览器,优先使用Fetch API;若需兼容IE或需要同步请求,可选择XMLHttpRequest。两者均为原生方案,无需依赖第三方库,是理解AJAX原理的基础。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值