浅析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 相关文章推荐
动态修改DOM 里面的 id 属性的弊端分析
Sep 03 Javascript
javascript弹出层输入框(示例代码)
Dec 11 Javascript
jquery操作checkbox火狐下第二次无法勾选的解决方法
Oct 10 Javascript
Javascript使用SWFUpload进行多文件上传
Nov 16 Javascript
JavaScript生成图形验证码
Aug 24 Javascript
浅谈react 同构之样式直出
Nov 07 Javascript
VUE Error: getaddrinfo ENOTFOUND localhost
May 03 Javascript
JavaScript学习笔记之DOM基础操作实例小结
Jan 09 Javascript
微信小程序提取公用函数到util.js及使用方法示例
Jan 10 Javascript
在NPM发布自己造的轮子的方法步骤
Mar 09 Javascript
JavaScript多种页面刷新方法小结
Apr 04 Javascript
解决await在forEach中不起作用的问题
Feb 25 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
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
输入密码检测大写是否锁定js实现代码
2012/12/03 Javascript
JavaScript在IE和FF下的兼容性问题
2014/05/19 Javascript
javascript实现仿腾讯游戏选择
2015/05/14 Javascript
JavaScript简单修改窗口大小的方法
2015/08/03 Javascript
微信小程序 Storage API实例详解
2016/10/02 Javascript
JS中Safari浏览器中的Date
2017/07/17 Javascript
vue动态绑定组件子父组件多表单验证功能的实现代码
2018/05/14 Javascript
react 中父组件与子组件双向绑定问题
2019/05/20 Javascript
layui实现把数据表格时间戳转换为时间格式的例子
2019/09/12 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
闭包在python中的应用之translate和maketrans用法详解
2014/08/27 Python
Python的Django框架中URLconf相关的一些技巧整理
2015/07/18 Python
Python脚本实现虾米网签到功能
2016/04/12 Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
2018/03/04 Python
用python简单实现mysql数据同步到ElasticSearch的教程
2018/05/30 Python
Python中collections模块的基本使用教程
2018/12/07 Python
jenkins配置python脚本定时任务过程图解
2019/10/29 Python
python3实现单目标粒子群算法
2019/11/14 Python
如何基于Python实现电子邮件的发送
2019/12/16 Python
IronPython连接MySQL的方法步骤
2019/12/27 Python
ansible动态Inventory主机清单配置遇到的坑
2020/01/19 Python
Python3运算符常见用法分析
2020/02/14 Python
Pytest测试框架基本使用方法详解
2020/11/25 Python
纯CSS实现预加载动画效果
2017/09/06 HTML / CSS
CSS中垂直居中的简单实现方法
2015/07/06 HTML / CSS
酒店管理专业学生求职信
2013/09/27 职场文书
幼儿园大班毕业感言
2014/02/06 职场文书
住宅使用说明书
2014/05/09 职场文书
工作粗心大意检讨书
2014/09/18 职场文书
2014年医院党建工作总结
2014/12/20 职场文书
工会文体活动总结
2015/05/07 职场文书
2016年庆祝六一儿童节活动总结
2016/04/06 职场文书
Spring Data JPA的Audit功能审计数据库的变更
2021/06/26 Java/Android
MySQL 十大常用字符串函数详解
2021/06/30 MySQL
mysql sum(if())和count(if())的用法说明
2022/01/18 MySQL