Ajax技术详解:从原生XMLHttpRequest到Fetch API及跨域处理

作者:资源驿站

时间:2026-10-30

浏览:338

本文深入解析Ajax技术,从原生XMLHttpRequest对象的创建、配置到发送请求的完整流程,对比jQuery、Vue.js、Angular等框架中的封装用法。重点讲解基于Promise的Fetch API优势,并详细阐述代理与XHR Level2两种主流跨域解决方案,帮助开发者掌握异步数据交互的核心原理。

文章目录

Ajax技术概述

Ajax作为当前Web开发中广泛采用的技术,具有极高的研究与探讨价值。本文将梳理Ajax的技术演进历程,并结合各大主流库与框架的具体应用场景,系统介绍Ajax从传统语法到现代新语法的演变与使用方式。

Ajax简介

Ajax全称为“Asynchronous Javascript And XML”,即“异步JavaScript和XML”。借助Ajax技术,开发者可以在不阻塞页面加载的前提下向服务器发送请求并进行数据交互,这本质上是一种异步数据传输机制。通过Ajax实现网页局部刷新,不仅减少了冗余数据的传输量,大幅提升了用户体验,还缩短了用户的等待时间,使得Web应用程序更加轻量、高效且友好。

上述内容属于基础常识,合格的开发人员通常已非常熟悉。此处仅为入门新手提供简要介绍,如需了解更多关于Ajax的基础知识,建议参考W3School的相关教程:http://www.w3school.com.cn/php/php_ajax_intro.asp

原生Ajax实现详解

原生Ajax

现代浏览器普遍支持原生Ajax功能。接下来,我们将详细解析如何利用原生JavaScript发起和处理Ajax请求。

1.获取XMLHttpRequest对象

var xhr = new XMLHttpRequest(); // 获取浏览器内置的XMLHttpRequest对象

若项目无需兼容低版本IE浏览器,可直接使用内置的XMLHttpRequest对象,Firefox、Chrome、Safari及Opera等现代浏览器均支持。如需兼容IE5或IE6等老版本IE,则需使用ActiveX对象。


var xhr;
if (window.XMLHttpRequest) {
  xhr=new XMLHttpRequest();
} else if (window.ActiveXObject) {  // 兼容老版本浏览器
  xhr=new ActiveXObject("Microsoft.XMLHTTP");
}

2.参数配置

获取XMLHttpRequest对象后,需通过open方法配置请求参数以完成数据交互。


var xhr;
if (window.XMLHttpRequest) {
  xhr=new XMLHttpRequest();
} else if (window.ActiveXObject) {
  xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
if (xhr) {
  xhr.open('GET', '/test/', true); // 以GET请求的方式向'/test/'路径发送异步请求
}

open方法用于创建一个新的HTTP请求。其第一个参数指定请求方式,通常为'GET'或'POST';第二个参数为请求的URL地址;第三个参数指定是否异步,默认值为true。

3.发送请求

完成基本参数配置后,直接调用send方法即可发送请求。


var xhr;
if (window.XMLHttpRequest) {
  xhr=new XMLHttpRequest();
} else if (window.ActiveXObject) {
  xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
if (xhr) {
  xhr.open('GET', '/test/', true); 
  xhr.send(); // 调用send方法发送请求
}

需注意GET与POST传参的区别:若使用GET方法,参数可直接附加在URL末尾,例如'/test/?name=luozh&size=12';若使用POST方法,参数需写入send方法中。


xhr.open('POST', '/test/', true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 将请求头设置为表单方式提交
xhr.send('name=luozh&size=12');

此时数据将以Form Data的形式进行传递。

Ajax技术概述

若不手动设置请求头,原生Ajax默认使用Content-Type为'text/plain;charset=UTF-8'的方式发送数据。若按上述参数书写,最终传输格式如下。

Ajax技术概述

显然,这种格式并非服务器期望的数据格式。因此,我们可以采用以下方式进行调整。


xhr.open('POST', '/test/', true);
xhr.send(JSON.stringify({name: 'luozh', size: 12}));

调整后的最终传输格式如下。

Ajax技术概述

通过这种方式,我们可以直接向后台传递JSON字符串进行处理,当然后台也需进行相应的配置以支持该格式。

4.监测状态

发送Ajax请求后,需对服务器返回的状态进行监测并作出相应处理,这可以通过onreadystatechange方法实现。


var xhr;

if (window.XMLHttpRequest) {
  xhr=new XMLHttpRequest();
} else if (window.ActiveXObject) {
  xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
if (xhr) {
  xhr.open('GET', '/test/', true);   // 以GET请求的方式向'/test/'路径发送异步请求
  xhr.send();
  xhr.onreadystatechange = function () {  // 利用onreadystatechange监测状态
    if (xhr.readyState === 4) {  // readyState为4表示请求响应完成
      if (xhr.status === 200) {  // status为200表示请求成功
        console.log('执行成功');
      } else {
        console.log('执行出错');
      }  
    }
  }
}

上述代码利用onreadystatechange监测状态,并通过readyState属性获取当前状态。readyState共有5个阶段,当其值为4时,表示响应内容已解析完成,可在客户端调用。当readyState为4时,进一步通过status获取状态码,若状态码为200则执行成功代码,否则执行错误处理代码。

此外,可以使用onload来替代onreadystatechange等于4的情况,因为onload仅在状态为4时被调用。


xhr.onload = function () {  // 调用onload
  if (xhr.status === 200) {  // status为200表示请求成功
    console.log('执行成功');
  } else {
    console.log('执行出错');
  }  
}

需要注意的是,IE浏览器对onload属性的支持并不完善。除了onload,还存在其他相关事件。

  • onloadstart
  • onprogress
  • onabort
  • ontimeout
  • onerror
  • onloadend

等事件,有兴趣的开发者可以亲自实践这些事件的具体用途。

以上即为原生Ajax请求数据的常见代码示例。

主流框架中的Ajax应用

其他库框架中的Ajax

1.jQuery中的Ajax

作为使用人数最多的库,jQuery对原生Ajax代码进行了良好的封装,在兼容性和易用性方面均有显著提升,使得Ajax调用变得极为简便。以下是一段简单的jQuery Ajax代码示例。


$.ajax({
  method: 'GET', // 1.9.0本版前用'type'
  url: "/test/",
  dataType: 'json'
})
.done(function() {
  console.log('执行成功');
})
.fail(function() {
  console.log('执行出错');
})

与原生Ajax不同,jQuery中默认的Content-type为'application/x-www-form-urlencoded; charset=UTF-8'。如需了解更多jQuery Ajax的详细信息,可参考官方文档:http://api.jquery.com/jquery.ajax/

2.Vue.js中的Ajax

Vue.js作为当前热门的前端框架,其本身并不包含Ajax功能,而是通过插件形式在项目中额外引用。其官方推荐的Ajax插件为vue-resource,以下便是vue-resource的请求代码示例。


Vue.http.get('/test/').then((response) => {
  console.log('执行成功');
}, (response) => {
  console.log('执行出错');
});

vue-resource支持Promise API,同时兼容Firefox、Chrome、Safari、Opera及IE9+浏览器,但不兼容IE8,这与Vue本身不支持IE8一致。如需了解更多vue-resource的信息,可参考GitHub文档:https://github.com/vuejs/vue-resource

3.Angular.js中的Ajax

此处Angular.js中的Ajax主要指Angular的1.x版本,因为Angular 2及以上版本目前不建议在生产环境中直接使用。


var myApp = angular.module('myApp',[]);
var myCtrl = myApp.controller('myCtrl',['$scope','$http',function($scope, $http){
  $http({
    method: 'GET',
    url: '/test/',
    headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'} 
  }).success(function (data) {
    console.log('执行成功');
  }).error(function () {
    console.log('执行出错');
  });
}]);

在Angular中,需在控制器上注册一个$http事件,随后才能在内部执行Ajax操作。Angular Ajax默认的Content-type为'application/json;charset=UTF-8',因此若需使用表单方式提交,还需手动设置headers属性。如需了解更多Angular Ajax的信息,可参考官方文档:https://docs.angularjs.org/api/ng/service/$http(可能需要翻墙访问)。

4.React中的Ajax

在React中,推荐使用fetch来请求数据。当然,fetch不仅适用于React,也可用于Vue、Angular等其他框架,因为它已被目前主流浏览器所支持。其具体功能和用法将在下文进行讲解。

Fetch API与跨域处理

Fetch API

Fetch API基于Promise设计。由于Promise及Fetch API本身存在浏览器兼容性问题,部分浏览器暂时不支持Fetch API,浏览器兼容性情况如下。

Ajax技术概述

当然,我们可以通过使用一些插件来解决兼容性问题,例如fetch-polyfill、es6-promise、fetch-ie8等。

使用Fetch可以非常便捷地编写Ajax请求,以下对比原生XMLHttpRequest对象与Fetch的使用方式。

XMLHttpRequst API


// XMLHttpRequst API
var xhr = new XMLHttpRequest();
xhr.open('GET', '/test/', true);
xhr.onload = function() {
  console.log('执行成功');
};
xhr.onerror = function() {
  console.log('执行出错');
};
xhr.send();

Fetch API


fetch('/test/').then(function(response) {
  return response.json();
}).then(function(data) {
  console.log('执行成功');
}).catch(function(e) {
  console.log('执行出错');
});

可以看出,使用Fetch后代码更加简洁且语义化,链式调用方式使其更加流畅清晰。随着浏览器内核的不断完善,未来的XMLHttpRequest将逐渐被Fetch所替代。关于Fetch的详细介绍可参考:https://segmentfault.com/a/1190000003810652

跨域Ajax

介绍了各种Ajax API后,我们不能忽视一个重要的问题:跨域。本文将重点讲解Ajax跨域的处理方式。

处理Ajax跨域问题主要有以下4种方式。

  1. 利用iframe
  2. 利用JSONP
  3. 利用代理
  4. 利用HTML5提供的XMLHttpRequest Level2

第一与第二种方式读者应当十分熟悉,均属于前端范畴,此处不再赘述,本文重点阐述第三种与第四种方式。

利用代理的方式可以这样理解。

通过在同域名下的Web服务器端创建一个代理。

北京服务器(域名:www.beijing.com)

上海服务器(域名:www.shanghai.com)

例如,在北京的Web服务器后台(www.beijing.com/proxy-shanghaiservice.php)调用上海服务器(www.shanghai.com/services.php)的服务,然后将访问结果返回给前端。这样,前端调用北京同域名的服务,效果等同于调用上海的服务。

利用XMLHttpRequest Level2的方式需要后台对请求头进行相应配置。


// php语法
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET,POST');

以上的*号可以替换为允许访问的域名,*表示所有域名都可以访问。

由此可见,第3和第4种方式主要涉及后端处理,前端只需进行调用即可。

总结

无论Ajax语法如何多变,无论库和框架如何封装Ajax,其本质上只是一种实现异步数据交互的工具。我们只需理解原生JS中Ajax的实现原理,掌握XMLHttpRequest及Promise的概念和流程,便能在数据异步交互的时代游刃有余。

以上就是本文的全部内容,希望对大家有所帮助,同时也希望多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章