Ajax是目前很广泛的一门技术,也是很值得探讨和研究的一门技术。本文将针对Ajax的发展过程并结合其在不一样库框架中的使用方式来和你们分享下Ajax的那些新老语法。php
Ajax全称为“Asynchronous Javascript And XML”, 即“异步JavaScript和XML”的意思。经过Ajax咱们能够向服务器发送请,在不阻塞页面的状况下进行数据交互,也能够理解为异步数据传输。在Ajax的帮助下咱们的网页只需局部刷新便可更新数据的显示,减小了没必要要的数据量,大大提升了用户体验,缩短了用户等待的时间,使得web应用程序更小、更快,更友好。html
固然以上都是司空见惯的内容了,做为一名合格的开发人员基本都再熟悉不过了,这里只为那些刚入门的新手作一个简单的介绍。更多的关于Ajax的简介请移步W3School进行了解:http://www.w3school.com.cn/php/php_ajax_intro.asp前端
基本上全部现代的浏览器都支持原生Ajax的功能,下面就来详细介绍下利用原生JS咱们怎样来发起和处理Ajax请求。vue
var xhr = new XMLHttpRequest(); // 获取浏览器内置的XMLHttpRequest对象
若是你的项目应用不考虑低版本IE,那么能够直接用上面的方法,全部现代浏览器 (Firefox、Chrome、Safari 以及 Opera) 都内建了 XMLHttpRequest 对象。若是须要兼容老版本IE(IE五、IE6),那么可使用 ActiveX 对象:jquery
var xhr; if (window.XMLHttpRequest) { xhr=new XMLHttpRequest(); } else if (window.ActiveXObject) { // 兼容老版本浏览器 xhr=new ActiveXObject("Microsoft.XMLHTTP"); }
有了XMLHttpRequest对象,咱们还须要配置一些请求的参数信息来完成数据交互,利用open方法便可:git
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。angularjs
配置完了基本参数信息,咱们直接调用send方法发送请求,代码以下:es6
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方法里,如:github
xhr.open('POST', '/test/', true); xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 将请求头设置为表单方式提交 xhr.send('name=luozh&size=12');
最终会以Form Data的形式传递:web
若是不设置请求头,原生Ajax会默认使用Content-Type是'text/plain;charset=UTF-8'的方式发送数据,若是按照上面的参数书写形式,咱们最终传输的形式这样的:
显然这并非服务器指望的数据格式,咱们能够这样写:
xhr.open('POST', '/test/', true); xhr.send(JSON.stringify({name: 'luozh', size: 12}));
最终传输的格式以下:
这样咱们能够直接传递JSON字符串给后台处理,固然后台也许进行相应配置。
发送完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还有:
等事件,有兴趣的同窗能够亲自去实践它们的用处。
以上即是原生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/
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
这里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(可能须要FQ)
在React中我比较推荐使用fetch来请求数据,固然其不只适用于React,在任何一种框架如上面的Vue、Angular中均可以使用,由于其已经被目前主流浏览器所支持,至于其主要功能和用法,我在下面会作下讲解。
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的详细介绍能够移步:http://www.javashuo.com/article/p-cqggfgkp-ec.html
介绍了各类各样的Ajax API,咱们不能避免的一个重要问题就是跨域,这里重点讲解下Ajax跨域的处理方式。
处理Ajax跨域问题主要有如下4种方式:
利用iframe
利用JSONP
利用代理
利用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的概念和流程,即可以轻松的在数据异步交互的时代游刃有余。
原创文章,转载请注明来自 劳卜 - 博客园[http://www.cnblogs.com/luozhihao]
本文地址:http://www.cnblogs.com/luozhihao/p/5846925.html
本文同步发表于:
segmentfault:http://www.javashuo.com/article/p-cpsqmnqw-hm.html
微信公众号“前端呼啦圈”(Love-FED)