Ajax是目前很普遍的一门技术,也是很值得探讨和研究的一门技术。本文将针对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的功能,下面就来详细介绍下利用原生JS我们怎样来发起和处理Ajax请求。

1.获取XMLHttpRequest对象

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

如果你的项目应用不考虑低版本IE,那么可以直接用上面的方法,所有现代浏览器 (Firefox、Chrome、Safari 以及 Opera) 都内建了 XMLHttpRequest 对象。如果需要兼容老版本IE(IE5、IE6),那么可以使用 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方法传递参数,我们可以直接将参数放在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会默认使用Content-Type是'text/plain;charset=UTF-8'的方式发送数据,如果按照上面的参数书写形式,我们最终传输的形式这样的:

显然这并不是服务器期望的数据格式,我们可以这样写:

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

最终传输的格式如下:

这样我们可以直接传递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

1.jQuery中的Ajax

jQuery作为一个使用人数最多的库,其Ajax很好的封装了原生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.×版本,因为Angular2目前还不建议在生产环境中使用。

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来请求数据,当然其不仅适用于React,在任何一种框架如上面的Vue、Angular中都可以使用,因为其已经被目前主流浏览器所支持,至于其主要功能和用法,我在下面会做下讲解。

Fetch API

Fetch API 是基于 Promise 设计,由于Promise的浏览器兼容性问题及Fetch API本身的兼容问题,一些浏览器暂时不支持Fetch API,浏览器兼容图如下:

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

使用Fetch我们可以非常便捷的编写Ajax请求,我们用原生的XMLHttpRequst对象和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

第1和第2种方式大家应该都非常熟悉,都属于前端的活,这里就不做介绍了,这里主要介绍第3和第4种方式。

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

通过在同域名下的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的概念和流程,便可以轻松的在数据异步交互的时代游刃有余。

Ajax语法浅析的更多相关文章

  1. Ajax 语法

    /*** * ajax语法 * * ***/ $.ajax({ async:false, //同步请求 url:"XXXXX.do",//请求后台地址 data: {"p ...

  2. ajax语法

    js语言功能比较强大,但不能访问数据库 ajax来补充这一缺陷 特点:输出不用刷新页面,条件查询数据显示页面上一般不用它,因为需要造很多表格不如用嵌入php代码方式简单 ajax语法: $.ajax( ...

  3. Juery Ajax语法

    $.ajax({ url: "/ForgetCard/ForgetLogin",//方法路径URL data: { strUser: $("#textUser" ...

  4. jquery ajax 语法

    $("select[name=type_id]").change(function(e) {    var val=$(this).val();    $.ajax({       ...

  5. javascript ajax的语法

    ajax参数: 详细参数转到如下地址: http://www.w3school.com.cn/jquery/ajax_ajax.asp $.ajax语法: jQuery.ajax([settings] ...

  6. Ajax 简述与基础语法

    目录 Ajax 1. 原生 JS 实现 Ajax 2. 使用 Ajax 实现异步通信 a. Ajax 的基础语法 b. 用 Ajax 传递数据 i. 传递字符串数据 ii. 传递 JSON 数据 3. ...

  7. jquery管理ajax异步-deferred对象

    今天跟大家分享一个jquery中的对象-deferred.其实早在jquery1.5.0版本中就已经引入这个对象了.不过可能在实际开发过程中用到的并不多,所以没有太在意. 这里先不说deferred的 ...

  8. Ajax调用SpringMVC ModelAndView 无返回情况

    在项目中使用Ajax的时候,success中返回的data一直都是null,也没有报错.在确定Ajax语法没有错误,也没有牵扯跨域问题后,用排除法挨着删除代码,发现是因为Spring MVC会自动把方 ...

  9. Ajax 技术一

    一.Ajax概述 1.历史起源 1998年,微软公司Outlook Web Access研发小组在当时的IE浏览器中集成了一种技术,可以在客户端无刷新的前提下向服务器端发送Http请求,这门技术称之为 ...

随机推荐

  1. js和jquery实现简单的选项卡

    选项卡切换在做网页的时候经常会用到,以往都是用JQ来实现,代码简单易懂,今天用原生的js实现了一下,二者还是有很大不同的,可以对比一下代码来研究一下. <!DOCTYPE html> &l ...

  2. CRL快速开发框架系列教程二(基于Lambda表达式查询)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  3. jQuery-template.js学习

    花了点时间,看了下jQuery-template.js,不多废话,先上结构 jQuery.each({..},function(){}) jQuery.fn.extend({..}) jQuery.e ...

  4. 劈荆斩棘:Gitlab 部署 CI 持续集成

    阅读目录: install configue gitlab-ci-multi-runner restore nuget packages bulid .sln run unit tests confi ...

  5. YYModel 源码解读(二)之YYClassInfo.h (3)

    前边3篇介绍了YYClassinfo 文件的组成单元,算是功能的分割,按照业务的设计思想来说,方向应该是相反的 由此引申出我们在设计api的思想其实和项目管理是很类似的----- 一些题外话 1.目的 ...

  6. 如何重置硬盘遭到“损坏”的Linux系统root用户密码

    传统印象下Linux是非常坚不可摧的,具有千年不更新,万年不重启的美名.而随着虚拟化的推进,很多跑在虚拟化上的Linux由于先前基础架构的脆弱,变得适应性“越来越不好”,体现在IP存储如果出现节点故障 ...

  7. 探寻 JavaScript 逻辑运算符(与、或)的真谛

    十二月已经过半,冬季是一个美妙的季节,寒冷的空气逼得人们不得不躲在安逸舒适的环境里生活.冬季会给人一种安静祥和的氛围,让人沉浸在其中,仿佛是一个旧的阶段的结束,同时也是一个新的阶段的开始.这么说来,西 ...

  8. FFmpeg学习4:音频格式转换

    前段时间,在学习试用FFmpeg播放音频的时候总是有杂音,网上的很多教程是基于之前版本的FFmpeg的,而新的FFmepg3中audio增加了平面(planar)格式,而SDL播放音频是不支持平面格式 ...

  9. Angular2 小贴士-多级注入器

    angular2 的依赖注入包含了太多的内容,其中的一个重点就是注入器,而注入器又非常难理解,今天我们不深入介绍注入器的内容,可以参考官方文档,我们今天来说注入器的层级. 也就是组件获取服务的容器会选 ...

  10. ICSharpCode.SharpZipLib 压缩、解压文件 附源码

    http://www.icsharpcode.net/opensource/sharpziplib/ 有SharpZiplib的最新版本,本文使用的版本为0.86.0.518,支持Zip, GZip, ...