浅析Ajax语法


Posted in Javascript onDecember 05, 2016

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语法

如果不设置请求头,原生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

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(可能需要FQ)

4.React中的Ajax

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

Fetch API

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

浅析Ajax语法

当然我们可以通过使用一些插件来解决兼容性问题,比如: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的概念和流程,便可以轻松的在数据异步交互的时代游刃有余。

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

Javascript 相关文章推荐
发布一个基于javascript的动画类 Fx.js
Nov 05 Javascript
JavaScript高级程序设计 阅读笔记(二十一) JavaScript中的XML
Sep 14 Javascript
jquery 漂亮的删除确认和提交无刷新删除示例
Nov 13 Javascript
javascript实现框架高度随内容改变的方法
Jul 23 Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
Jan 19 Javascript
jquery实现全选功能效果的实现代码
May 05 Javascript
深入理解JavaScript函数参数(推荐)
Jul 26 Javascript
JS中动态创建元素的三种方法总结(推荐)
Oct 20 Javascript
AngularJS服务service用法总结
Dec 13 Javascript
javascript实现用户点击数量统计
Dec 25 Javascript
js的函数的按值传递参数(实例讲解)
Nov 16 Javascript
mpvue+vant app搭建微信小程序的方法步骤
Feb 11 Javascript
jQuery的事件预绑定
Dec 05 #Javascript
微信小程序 UI布局常用技巧整理总结
Dec 05 #Javascript
深入理解vue.js双向绑定的实现原理
Dec 05 #Javascript
微信小程序 底部导航栏目开发资料
Dec 05 #Javascript
基于js实现的限制文本框只可以输入数字
Dec 05 #Javascript
AJAX和jQuery动态加载数据的实现方法
Dec 05 #Javascript
Javascript中字符串replace方法的第二个参数探究
Dec 05 #Javascript
You might like
PHP编程中的常见漏洞和代码实例
2014/08/06 PHP
详解Laravel视图间共享数据与视图Composer
2016/08/04 PHP
Smarty3配置及入门语法
2017/02/22 PHP
php实现socket推送技术的示例
2017/12/20 PHP
常见的5个PHP编码小陋习以及优化实例讲解
2021/02/27 PHP
用JS剩余字数计算的代码
2008/07/03 Javascript
javascript工具库代码
2012/03/29 Javascript
js css后面所带参数含义介绍
2013/08/18 Javascript
js清除input中type等于file的值域(示例代码)
2013/12/24 Javascript
ExtJS4给Combobox设置列表中的默认值示例
2014/05/02 Javascript
JavaScript中统计Textarea字数并提示还能输入的字符
2014/06/10 Javascript
通过JS动态创建一个html DOM元素并显示
2014/10/15 Javascript
JS代码随机生成姓名、手机号、身份证号、银行卡号
2016/04/27 Javascript
30分钟快速掌握Bootstrap框架
2016/05/24 Javascript
node.js cookie-parser 中间件介绍
2016/06/06 Javascript
jQuery简单设置文本框回车事件的方法
2016/08/01 Javascript
angularJS+requireJS实现controller及directive的按需加载示例
2017/02/20 Javascript
nodejs使用express创建一个简单web应用
2017/03/31 NodeJs
bootstrap3 dialog 更强大、更灵活的模态框
2017/04/20 Javascript
jQuery实现radio第一次点击选中第二次点击取消功能
2017/05/15 jQuery
Javascript es7中比较实用的两个方法示例
2017/07/21 Javascript
Angular中点击li标签实现更改颜色的核心代码
2017/12/08 Javascript
详解VUE单页应用骨架屏方案
2019/01/17 Javascript
layui使用数据表格实现购物车功能
2019/07/26 Javascript
Vue如何循环提取对象数组中的值
2020/11/18 Vue.js
python中将一个全部为int的list 转化为str的list方法
2018/04/09 Python
Python 经典面试题 21 道【不可错过】
2018/09/21 Python
pytorch ImageFolder的覆写实例
2020/02/20 Python
编写html5时调试发现脚本php等网页js、css等失效
2013/12/31 HTML / CSS
什么是动态端口(Dynamic Ports)?动态端口的范围是多少?
2014/12/12 面试题
个人求职信范文分享
2014/01/06 职场文书
十八届三中全会个人学习材料
2014/02/13 职场文书
四议两公开实施方案
2014/03/28 职场文书
公休请假条
2014/04/11 职场文书
民事和解协议书格式
2014/11/29 职场文书
利用Sharding-Jdbc进行分库分表的操作代码
2022/01/22 Java/Android