深刻浅出Ajax

原文(个人GitHub):https://github.com/liangfengbo/frontend-ability/issues/1javascript

学习大纲

  1. 理解Ajax的工做原理
  2. Ajax核心-XMLHttpRequest对象
  3. 封装Ajax方法
  4. Ajax优缺点
  5. Ajax适应场景
  6. Ajax系列面试题总结

Ajax的工做原理

含义:

1. w3chool官网:Ajax 是一种在无需从新加载整个网页的状况下,可以更新部分网页的技术。
2. 个人理解:无须刷新页面便可从服务器取得数据的技术。

原理:

Ajax的工做原理至关于在用户和服务器之间加了—个中间层,使用户操做与服务器响应异步化。并非全部的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎本身来作, 只有肯定须要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。html

ajax

核心XMLHttpRequest对象

Ajax技术的核心是XMLHttpRequest对象。
  • IE5 XHR对象是经过MSXML库中的一个ActiveX对象实现的,因此要考虑作兼容。
  • IE7+、Firefox、Opera、Chrome和Safari都支持原生的XHR对象
new ActiveXObject(versions);

new XMLHttpRequest();

XMLHttpRequest 对象方法描述

方法 描述
abort() 中止当前请求
getAllResponseHeaders() 把HTTP请求的全部响应首部做为键/值对返回
getResponseHeader("header") 返回指定首部的串值
open("method","URL",[asyncFlag],["userName"],["password"]) 创建对服务器的调用。method参数能够是GET、POST或PUT。url参数能够是相对URL或绝对URL。这个方法还包括3个可选的参数,是否异步,用户名,密码
send(content) 向服务器发送请求
setRequestHeader("header", "value") 把指定首部设置为所提供的值。在设置任何首部以前必须先调用open()。设置header并和请求一块儿发送 ('post'方法必定要 )

XMLHttpRequest 对象属性描述

属性 描述
onreadystatechange 状态改变的事件触发器,每一个状态改变时都会触发这个事件处理器,一般会调用一个JavaScript函数
readyState 请求的状态。有5个可取值:0 = 未初始化,1 = 正在加载,2 = 已加载,3 = 交互中,4 = 完成
responseText 服务器的响应,返回数据的文本。
responseXML 服务器的响应,返回数据的兼容DOM的XML文档对象 ,这个对象能够解析为一个DOM对象。
responseBody 服务器返回的主题(非文本格式)
responseStream 服务器返回的数据流
status 服务器的HTTP状态码(如:404 = "文件末找到" 、200 ="成功" ,等等)
statusText 服务器返回的状态文本信息 ,HTTP状态码的相应文本(OK或Not Found(未找到)等等)

XMLHttpRequest进度事件

事件 描述
loadstart 在接收到响应数据的第一个字节时触发。
progress 在接收响应期间持续不断地触发。
error 在请求发生错误时触发。
abort 在由于调用abort()方法而终止链接时触发。
load 在接收到完整的响应数据时触发。
loadend 在通讯完成或者触发error、abort或load事件后触发。

封装ajax方法

/**
 * 建立Ajax
 * @param options
 */
function Ajax(options) {
  // 新建一个对象,用途接受XHR对象
  var xhr = null;

  // 第一步建立XMLHttpRequest对象 || 同时兼任IE
  // 首先检测原生XHR对象是否存在,若是存在则返回它的新实例
  if (typeof XMLHttpRequest != "undefined") {
    xhr = new XMLHttpRequest();

    // 而后若是原生对象不存在,则检测ActiveX对象
  } else if (typeof ActiveXObject != "undefined") {

    // 若是存在,则建立他的对象,但这个对象须要一个传入参数,以下:
    if (typeof arguments.callee.activeXString != 'string') {
      // 对象版本
      var versions = [
        'Microsoft.XMLHTTP',
        'Msxml2.XMLHTTP.7.0',
        'Msxml2.XMLHTTP.6.0',
        'Msxml2.XMLHTTP.5.0',
        'Msxml2.XMLHTTP.4.0',
        'MSXML2.XMLHTTP.3.0',
        'MSXML.XMLHTTP'
      ], i, len;

      for (i = 0, len = versions.length; i < len; i++) {
        try {
          // 须要versions数组中的某个项,数组的7个项分别对应7个版本.
          new ActiveXObject(versions[i]);

          // arguments是javascript函数的内置对象,表明传入参数的集合,
          // callee就表明对象自己即new createXHR
          arguments.callee.activeXString = versions[i];
          break;

        } catch (e) {
          // 跳过
        }
      }
    }
    // 直到循环建立成功为止,而后给本身添加一个属性叫activeXString
    xhr = new ActiveXObject(arguments.callee.activeXString);

  } else {
    // 若是这两种对象都不存在,就抛出一个错误
    throw new Error('No XHR object available');
  }

  /**
   ** options形参解析:
   * data 发送的参数,格式为对象类型
   * url 发送请求的url,服务器地址(api)
   * async 否为异步请求,true为异步的,false为同步的
   * method http链接的方式,包括POST和GET两种方式
   */
  options = options || {};
  options.success = options.success || function () {
  };
  options.fail = options.fail || function () {
  };

  var data = options.data,
       url = options.url,
       async = options.async === undefined ? true : options.async,
       method = options.method.toUpperCase(),
       dataArr = [];

  // 遍历参数
  for (var k in data) {
    dataArr.push(k + '=' + data[k]);
  }

  // GET请求
  if (method === 'GET') {
    url = url + '?' + dataArr.join('&');
    xhr.open(method, url.replace(/\?$/g, ''), async);
    xhr.send();
  }

  // POST请求
  if (method === 'POST') {
    xhr.open(method, url, async);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xhr.send(dataArr.join('&'));
  }

  // 响应接收完毕后将触发load事件
  xhr.onload = function () {

    /**
     * XHR对象的readyState属性
     * 0:未初始化。还没有调用open()方法。
     * 1:启动。已经调用open()方法,但还没有调用send()方法。
     * 2:发送。已经调用send()方法,但还没有接收到响应。
     * 3:接收。已经接收到部分响应数据。
     * 4:完成。已经接收到所有响应数据,并且已经能够在客户端使用了。
     */
    if (xhr.readyState == 4) {
      // 获得响应
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
        // 处理成功数据
        var res;
        if (options.success && options.success instanceof Function) {
          res = xhr.responseText;
          if (typeof res === 'string') {
            res = JSON.parse(res);
            options.success.call(xhr, res);
          }
        }
      } else {
        // 处理错误数据
        if (options.fail && options.fail instanceof Function) {
          options.fail.call(xhr, res)
        }
      }

    } else {
      // 抛出检测XHR对象的readyState属性
      console.log('XHR was readyState:', xhr.readyState);
    }
  }
}

options参数说明

参数 类型 描述 默认值 是否填
url string 发送请求的url,服务器地址(api) '' 必填
method string http链接的方式,包括POST和GET两种方式 true 选填
async boolean 是否为异步请求,true为异步的,false为同步的 true 选填
data json 发送的参数,格式为对象(json)类型 null 选填
success function 请求成功回调函数 function () { } 必填
fail function 请求失败回调函数 function () { } 必填

示例:

Ajax({
  url: 'http://localhost:3000/api/v1/article',
  method: 'GET',
  async: true,
  success: function (res) {
    console.log('successful', res);
  },
  fail: function (err) {
    console.log('fail', err);
  }
})

成功返回数据:

successful {code: 200, msg: "查询文章列表成功!", data: {…}}

ajax-1

ajax-2

Ajax优势

1.无刷新更新数据。

AJAX最大优势就是能在不刷新整个页面的前提下与服务器通讯维护数据。这使得Web应用程序更为迅捷地响应用户交互,并避免了在网络上发送那些没有改变的信息,减小用户等待时间,带来很是好的用户体验。前端

2.异步与服务器通讯。

AJAX使用异步方式与服务器通讯,不须要打断用户的操做,具备更加迅速的响应能力。优化了Browser和Server之间的沟通,减小没必要要的数据传输、时间及下降网络上数据流量。java

3.前端和后端负载平衡。

AJAX能够把之前一些服务器负担的工做转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。而且减轻服务器的负担,AJAX的原则是“按需取数据”,能够最大程度的减小冗余请求和响应对服务器形成的负担,提高站点性能。git

4.基于标准被普遍支持。

AJAX基于标准化的并被普遍支持的技术,不须要下载浏览器插件或者小程序,但须要客户容许JavaScript在浏览器上执行。随着Ajax的成熟,一些简化Ajax使用方法的程序库也相继问世。一样,也出现了另外一种辅助程序设计的技术,为那些不支持JavaScript的用户提供替代功能。github

5.界面与应用分离。

Ajax使WEB中的界面与应用分离(也能够说是数据与呈现分离),有利于分工合做、减小非技术人员对页面的修改形成的WEB应用程序错误、提升效率、也更加适用于如今的发布系统。面试

Ajax缺点

1.AJAX干掉了Back和History功能,即对浏览器机制的破坏。

在动态更新页面的状况下,用户没法回到前一个页面状态,由于浏览器仅能记忆历史记录中的静态页面。一个被完整读入的页面与一个已经被动态修改过的页面之间的差异很是微妙;用户一般会但愿单击后退按钮可以取消他们的前一次操做,可是在Ajax应用程序中,这将没法实现ajax

2.AJAX的安全问题

JAX技术给用户带来很好的用户体验的同时也对IT企业带来了新的安全威胁,Ajax技术就如同对企业数据创建了一个直接通道。这使得开发者在不经意间会暴露比之前更多的数据和服务器逻辑。Ajax的逻辑能够对客户端的安全扫描技术隐藏起来,容许黑客从远端服务器上创建新的攻击。还有Ajax也难以免一些已知的安全弱点,诸如跨站点脚步攻击、SQL注入攻击和基于Credentials的安全漏洞等等数据库

3.对搜索引擎支持较弱。

对搜索引擎的支持比较弱。若是使用不当,AJAX会增大网络数据的流量,从而下降整个系统的性能。json

4.破坏程序的异常处理机制。

至少从目前看来,像Ajax.dll,Ajaxpro.dll这些Ajax框架是会破坏程序的异常机制的。关于这个问题,曾在开发过程当中遇到过,可是查了一下网上几乎没有相关的介绍。后来作了一次试验,分别采用Ajax和传统的form提交的模式来删除一条数据……给咱们的调试带来了很大的困难

5.AJAX不能很好支持移动设备。

一些手持设备(如手机、PDA等)如今还不能很好的支持Ajax,好比说咱们在手机的浏览器上打开采用Ajax技术的网站时,它目前是不支持的。

Ajax适用场景

  • 表单驱动的交互
  • 深层次的树的导航
  • 快速的用户与用户间的交流响应
  • 相似投票、yes/no等无关痛痒的场景
  • 对数据进行过滤和操纵相关数据的场景
  • 普通的文本输入提示和自动完成的场景

Ajax不适用场景

  • 部分简单的表单
  • 搜索
  • 基本的导航
  • 替换大量的文本
  • 对呈现的操纵

Ajax常见面试题:

一、Ajax是什么?如何建立一个Ajax?

Ajax并不算是一种新的技术,全称是asychronous javascript and xml,能够说是已有技术的组合,主要用来实现客户端与服务器端的异步通讯效果,实现页面的局部刷新,早期的浏览器并不能原生支持ajax,可使用隐藏帧(iframe)方式变相实现异步效果,后来的浏览器提供了对ajax的原生支持

使用ajax原生方式发送请求主要经过XMLHttpRequest(标准浏览器)、ActiveXObject(IE浏览器)对象实现异步通讯效果

基本步骤:

var xhr =null;//建立对象 

if(window.XMLHttpRequest){

xhr = new XMLHttpRequest();

}else{

xhr = new ActiveXObject("Microsoft.XMLHTTP");

}

xhr.open(“方式”,”地址”,”标志位”);//初始化请求 

xhr.setRequestHeader(“”,””);//设置http头信息 

xhr.onreadystatechange =function(){}//指定回调函数 

xhr.send();//发送请求

js框架(jQuery/EXTJS等)提供的ajax API对原生的ajax进行了封装,熟悉了基础理论,再学习别的框架就会驾轻就熟,好多都是换汤不换药的内容

二、同步和异步的区别?

同步:阻塞的

  • 张三叫李四去吃饭,李四一直忙得不停,张三一直等着,直到李四忙完两我的一块去吃饭,浏览器向服务器请求数据,服务器比较忙,浏览器一直等着(页面白屏),直到服务器返回数据,浏览器才能显示页面

异步:非阻塞的

  • 张三叫李四去吃饭,李四在忙,张三说了一声而后本身就去吃饭了,李四忙完后本身去吃,浏览器向服务器请求数据,服务器比较忙,浏览器能够自如的干原来的事情(显示页面),服务器返回数据的时候通知浏览器一声,浏览器把返回的数据再渲染到页面,局部更新

三、如何解决跨域问题?

理解跨域的概念:协议、域名、端口都相同才同域,不然都是跨域

出于安全考虑,服务器不容许ajax跨域获取数据,可是能够跨域获取文件内容,因此基于这一点,能够动态建立script标签,使用标签的src属性访问js文件的形式获取js脚本,而且这个js脚本中的内容是函数调用,该函数调用的参数是服务器返回的数据,为了获取这里的参数数据,须要事先在页面中定义回调函数,在回调函数中处理服务器返回的数据,这就是解决跨域问题的主流解决方案

四、页面编码和被请求的资源编码若是不一致如何处理?

对于ajax请求传递的参数,若是是get请求方式,参数若是传递中文,在有些浏览器会乱码,不一样的浏览器对参数编码的处理方式不一样,因此对于get请求的参数须要使用encodeURIComponent函数对参数进行编码处理,后台开发语言都有相应的解码api。对于post请求不须要进行编码

五、简述ajax的过程。

  1. 建立XMLHttpRequest对象,也就是建立一个异步调用对象
  2. 建立一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
  3. 设置响应HTTP请求状态变化的函数
  4. 发送HTTP请求
  5. 获取异步调用返回的数据
  6. 使用JavaScript和DOM实现局部刷新

六、阐述一下异步加载JS。

  1. 异步加载的方案: 动态插入 script 标签
  2. 经过 ajax 去获取 js 代码,而后经过 eval 执行
  3. script 标签上添加 defer 或者 async 属性
  4. 建立并插入 iframe,让它异步执行 js

七、请解释一下 JavaScript的同源策略。‘’

同源策略是客户端脚本(尤为是Javascript)的重要的安全度量标准。它最先出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不一样源装载。所谓同源指的是:协议,域名,端口相同,同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。

八、GET和POST的区别,什么时候使用POST?

GET:通常用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,通常在2000个字符,有的浏览器是8000个字符

POST:通常用于修改服务器上的资源,对所发送的信息没有限制

在如下状况中,请使用 POST 请求:

  1. 没法使用缓存文件(更新服务器上的文件或数据库)
  2. 向服务器发送大量数据(POST 没有数据量限制)
  3. 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

九、ajax是什么?ajax的交互模型?同步和异步的区别?如何解决跨域问题?

  1. 经过异步模式,提高了用户体验
  2. 优化了浏览器和服务器之间的传输,减小没必要要的数据往返,减小了带宽占用
  3. Ajax在客户端运行,承担了一部分原本由服务器承担的工做,减小了大用户量下的服务器负载。

十、 Ajax的最大的特色是什么。

Ajax能够实现异步通讯效果,实现页面局部刷新,带来更好的用户体验;按需获取数据,节约带宽资源;

十一、ajax的缺点

一、ajax不支持浏览器back按钮。

二、安全问题 AJAX暴露了与服务器交互的细节。

三、对搜索引擎的支持比较弱。

四、破坏了程序的异常机制。

十二、ajax请求的时候get和post方式的区别

get通常用来进行查询操做,url地址有长度限制,请求的参数都暴露在url地址当中,若是传递中文参数,须要本身进行编码操做,安全性较低。

post请求方式主要用来提交数据,没有数据长度的限制,提交的数据内容存在于http请求体中,数据不会暴漏在url地址中。

1三、解释jsonp的原理,以及为何不是真正的ajax

Jsonp并非一种数据格式9,而json是一种数据格式,jsonp是用来解决跨域获取数据的一种解决方案,具体是经过动态建立script标签,而后经过标签的src属性获取js文件中的js脚本,该脚本的内容是一个函数调用,参数就是服务器返回的数据,为了处理这些返回的数据,须要事先在页面定义好回调函数,本质上使用的并非ajax技术

1四、什么是Ajax和JSON,它们的优缺点。

Ajax是全称是asynchronous JavaScript andXML,即异步JavaScript和xml,用于在Web页面中实现异步数据交互,实现页面局部刷新。

优势:可使得页面不重载所有内容的状况下加载局部内容,下降数据传输量,避免用户不断刷新或者跳转页面,提升用户体验

缺点:对搜索引擎不友好;要实现ajax下的先后退功能成本较大;可能形成请求数的增长跨域问题限制;

JSON是一种轻量级的数据交换格式,ECMA的一个子集

优势:轻量级、易于人的阅读和编写,便于机器(JavaScript)解析,支持复合数据类型(数组、对象、字符串、数字)

1五、http常见的状态码有那些?分别表明是什么意思?

200 - 请求成功

301 - 资源(网页等)被永久转移到其它URL

404 - 请求的资源(网页等)不存在

500 - 内部服务器错误

1六、一个页面从输入 URL到页面加载显示完成,这个过程当中都发生了什么?

分为4个步骤:

  1. 当发送一个 URL 请求时,无论这个 URL 是 Web 页面的 URL 仍是 Web 页面上每一个资源的 URL,浏览器都会开启一个线程来处理这个请求,同时在远程 DNS 服务器上启动一个 DNS 查询。这能使浏览器得到请求对应的 IP 地址。
  2. 浏览器与远程 Web 服务器经过 TCP 三次握手协商来创建一个 TCP/IP 链接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试创建起通讯,然后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。
  3. 一旦 TCP/IP 链接创建,浏览器会经过该链接向远程服务器发送 HTTP 的 GET 请求。远程服务器找到资源并使用 HTTP 响应返回该资源,值为 200 的 HTTP 响应状态表示一个正确的响应。
  4. 此时,Web 服务器提供资源服务,客户端开始下载资源。

1七、ajax请求的时候get和post方式的区别

get通常用来进行查询操做,url地址有长度限制,请求的参数都暴露在url地址当中,若是传递中文参数,须要本身进行编码操做,安全性较低。

post请求方式主要用来提交数据,没有数据长度的限制,提交的数据内容存在于http请求体中,数据不会暴漏在url地址中。

1八、ajax请求时,如何解释json数据
使用eval() 或者JSON.parse() 鉴于安全性考虑,推荐使用JSON.parse()更靠谱,对数据的安全性更好。

参考文档

JavaScript高级程序设计第三版
AJAX工做原理及其优缺点
Ajax原理以及优缺点
Ajax的工做原理
Ajax系列面试题总结01

相关文章
相关标签/搜索