Ajax 知识点的那些事

2018-07-12 admin

Ajax是什么

AJAX即“Asynchronous JavaScript and XML”(异步的JavaScript与XML技术),指的是一套综合了多项技术的浏览器端网页开发技术,包含了HTML、CSS、JavaScript、DOM、XML等技术。Aiax 只是一个哥们“发明”的缩写,这个新术语用来描述一种使用现有技术集合的一个名称。多项技术中最重要的是 XMLHttpRequest 对象,稍后会介绍到它。

如果不使用 Ajax,仔细观察一个Form的提交,你就会发现,一旦用户点击“Submit”按钮,表单开始提交,浏览器就会刷新页面,然后会跳到新页面里告诉你操作是成功了还是失败了。如果失败了,还要返回表单填写页,有些信息会丢失,需要重新填写,这对用户体验极其不友好。

这是Web的运作原理:一次HTTP请求对应一个页面。

如果要让用户留在当前页面中,同时发出新的HTTP请求,就必须用JavaScript发送这个新请求,接收到数据后,再用JavaScript更新页面,这样一来,用户就感觉自己仍然停留在当前页面,数据却可以不断地更新。

也就是说,当使用了 Ajax 后,可以在不重新刷新页面的情况下与服务器通信,交换数据,更新页面, 这样能够快速地将数据更新呈现在用户界面上,这使得程序能够更快地回应用户的操作。

可以利用 Ajax 的特性做如下事情:

  • 在不重新加载页面的情况下发送请求给服务器
  • 接受并使用从服务器响应的数据。

交换的数据格式

使用 AJAX 技术中的 XMLHttpRequest 对象与服务器通信,交换数据。数据的格式可以使用JSON,XML,HTML和文本等多种格式发送和接收。尽管X在Ajax中代表XML, 但由于JSON的许多优势,更加轻量以及是Javascript的一部分,目前JSON的使用比XML更加普遍。

关于JSON

JSON(JavaScript Object Notation) 是一种轻级的数据交换格式。JSON实际上是JavaScript的一个子集。但是和JavaScript的语法稍微有些不同,有属于JSON自己的语法。

JSON构建于两种形式:

  1. 无序的“‘名称/值’对”集合 一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
  2. 值的有序列表 一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。

在JSON中值支持以下几种数据类型:

  • number:和JavaScript的number完全一致,在JSON中数字不能以0开头。
  • boolean:JavaScript的true或false;
  • string:JavaScript的string;
  • null:JavaScript的null;
  • array:JavaScript的Array表示方式——[];在JSON中结尾不能有逗号。
  • object:JavaScript的{ … }表示方式。在JSON中结尾不能有逗号,key值必须加上双引号。

在JavaScript中,可以直接使用JSON,JavaScript内置了JSON的解析。

JSON 对象

JSON对象定义在全局,该对象包含了两个方法,除了这两个方法, JSON这个对象本身并没有其他作用,也不能被调用或者作为构造函数调用。

JSON.stringify()

JavaScript 中的对象或数组序列化成JSON字符串。简单来说 JSONJavaScript 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。

序列化将对象的状态信息转换为可以存储或传输的形式的过程。

例如在 JavaScript 中定义的对象:

let obj = {a:1,b:2}

此对象存在于内存中,并不能将期结构存储在cookie或localStorage或传递给后端。而此时就需要调用此方法序列换为一个 JSON 字符串。

console.log(JSON.stringify(obj)); // {"a":1,"b":2}

JSON.parse()JSON 字符串反序列化成 JavaScript 中的对象或数组。JSON 字符串本身只是一个字符串,不能通过属性名的方式获取对应的值。要转换为对象就可以使用 key 来取值。

反序列化将可以存储或传输的形式转换为对象的过程。

例如从后端拿到一个 JSON 字符串 :

let objStr = ‘{“a”:1,“b”:2}’

此时不能使用 objStr.a 取到数值1,因为 objStr 本身只是一个字符串值,并不是对象。

需要把JSON 字符串转成可用的对象:

console.log(JSON.parse(objStr)); // {“a”:1,“b”:2}

异步

Ajax 中的Asynchronous 是异步的意思,结合 Ajax 可以和服务器进行通信,可以说Ajax是用JavaScript执行异步的网络请求。

所谓的异步就是,一个异步过程调用发出后,调用者不会立刻得到结果。而是在 调用 发出后,_被调用者_通过状态、通知来通知调用者,或通过回调函数处理这个调用。

其中DOM事件,定时器就是典型的异步操作。拿定时器举例,当调用 setTimeout 函数时候,就发起了一个异步操作,此时不会立马得到反馈,而到了设置的时间,会调用传入的回调函数,一旦回调函数执行就得到通知说明异步完成了。

setTimeout(function(){
    console.log('执行此回调函数,异步完成得到通知,该干嘛干嘛!!!');
}, 1000)

与之对应的还有一个同步的概念,所谓同步,就是在发出一个_调用_时,在没有得到结果之前,该_调用_就不返回。但是一旦调用返回,就得到返回值了。由_调用者_主动等待这个_调用_的结果。

比如拿一个 JavaScript 中函数调用举例:

var arr = [1,2,3,4,5,6,7,8];

arr.map((item) => {
    return item * 2
})

arr.forEach((item) => {
    return item * 2
})

上述代码中只有 map 指向之后,得到了结果,才能继续调用 forEach, 这是一个同步调用的过程。

在使用 Ajax 时候,发出的是一个异步请求,要通过调用函数获得响应。

分解Ajax中的知识点

使用 JavaScript 创建一个请求对象实例,调用该实例下的方法,设置好请求的URL地址和请求数据,发送异步请求。发送后等待服务端响应,响应是以触发事件来通知,随后通过请求对象实例拿到HTTP状态以及响应的内容。

完成一次请求,代码示意如下所示

let xhr = new XMLHttpRequest;

console.log(xhr.readyState); // 0 UNSENT 创建实例对象,尚未调用open();

xhr.open('GET','http://kuapi.wykiss.cn/api?json=true',true);

console.log(xhr.readyState); // 1 OPENED open()方法已成功调用。

// 当readyState状态发生变化时,触发此事件

xhr.onreadystatechange = function () {
    console.log(xhr.readyState);
    if(xhr.readyState === 2){ // 2 HEADERS_RECEIVED 可以获取到响应头信息
        console.log('响应头信息为:',xhr.getAllResponseHeaders())
    }else if(xhr.readyState === 3){ // 3 LOADING 正在接收部分响应内容 
        console.log('接收的部分内容是:',xhr.response)
    }else if(xhr.readyState === 4) { // 4 DONE 请求操作已经完成,响应的内容全部接受完成
        console.log('接收全部内容是:',xhr.response) 
    }
}

// 请求操作完成 触发的事件
xhr.onload = function () {
    console.log('请求操作完成,触发此事件')
    console.log('可以直接获取响应的全部内容',xhr.response)
}

xhr.send();

咋眼一看,内容还挺多,分解每一个知识点如下。

XMLHttpRequest 对象

XMLHttpRequest 是规范制定的API,已经被现代浏览器广泛使用,它为客户端提供了在客户端和服务器之间传输数据的功能,是Ajax技术的核心所在。

全局会提供一个 XMLHttpRequest 构造函数来初始化一个请求实例对象。

var xhr = new XMLHttpRequest();

此对象上会有多个属性和方法。

图片描述

readyState 属性

只读属性,xhr.readyState 记录了请求实例对象运行过程中所处的状态,使用数字来表示。以下是每个数字代表的含义:

状态 描述
0 UNSENT 请求对象已创建,尚未调用 open()方法
1 OPENED open()方法已成功调用
2 HEADERS_RECEIVED send() 方法已调用,可以获取到响应头信息
3 LOADING 正在接收部分响应内容
4 DONE 请求操作已经完成,响应的内容全部接受完成

response 和responseText 属性

两个都是只读属性,存的是服务器的响应内容。 responseText表示服务器响应内容的文本形式。

responseType 属性

可读可写属性,xhr.responseType 表示响应的类型, 缺省为空字符串, 可取 “arraybuffer” , “blob” , “document” , “json” , and “text” 共五种类型。 当将responseType设置为一个特定的类型时,你需要确保服务器所返回的类型和你所设置的返回值类型是兼容的。那么如果两者类型不兼容,服务器返回的数据变成了null,即使服务器返回了数据。还有一个要注意的是,给一个同步请求设置responseType会抛出一个InvalidAccessError 的异常。

responseURL 属性

xhr.responseURL 返回ajax请求最终的URL, 如果请求中存在重定向, 那么responseURL表示重定向之后的URL。

status 属性

只读属性。xhr.status存的是数字状态码,是标准的HTTML状态码。在请求完成前,status的值为0。如果请求出错,浏览器返回的 status 也为0。如果服务器响应中没有明确指定status码, status码将会默认为200。

statusText 属性

只读属性。xhr.status存的是服务器返回的状态短语。这个属性包含了返回状态对应的文本信息,例如"OK"或是"Not Found"。

open() 方法

xhr.open() 方法初始化一个请求。

语法:

xhr.open(method, url) xhr.open(method, url, async)

  • method 要使用的HTTP方法,比如 「GET」、「POST」、「PUT」、「DELETE」等。常用的是「GET」、「POST」请求方式。其他的方法后端需要特别的支持。

接下来讨论的是在浏览器应用层面中GET和POST发送数据的不同。

- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。

  • url 发送请求的URL地址。如果发送的是 get 请求要把数据写在地址栏的后面发送给后端。例如:

http://kuapi.wykiss.cn/api?js…

  • async 可选参数。默认为true,表示执行是不是执行异步操作。true,为异步,false,为同步。当设置false时,浏览器会出现一个警告。

    • 异步请求发出后,调用者不会立刻得到结果。而是在 调用 发出后,_被调用者_通过触发事件,调用事件处理回调函数。在没有得到后端返回的结果之前,异步操作之后的代码会继续执行。
    // Ajax 发出异步请求
    // ..... 代码省略
    console.log('没得到结果,我先执行');
    
    • 同步请求发出后,在没有得到结果之前,该_调用_就不返回。这就意味着,后续的代码不能被执行,只有等到同步调用结束后得到了结果,才能继续执行代码。
    // Ajax 发出同步请求
    // ..... 代码省略
    console.log('只有同步操作完成后,我才能执行');
    

send() 方法

xhr.send() 方法用于发送 HTTP 请求。如果是异步请求(默认为异步请求),则此方法会在请求发送后立即返回,接着继续执行send后面的代码;如果是同步请求,则此方法直到服务端响应结束后全部拿到响应的数据后才会返回。

xhr.send() 方法接受一个可选的参数,其作为请求主体,发送 post 时会用到;如果请求方法是 GET,则应将请求主体设置为 null。

注意:请求方法为 post 时,要在请求头(headers)中的 Content-Type 设置消息主体编码方式,这样服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。

  • application/x-www-form-urlencoded

Content-Type 被指定为 application/x-www-form-urlencoded;提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。例如 PHP 中,$_ POST[’ json '] 可以获取到 true 的值,$_POST[‘country’] 可以得到 中国 值。

xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send('json=true&country=中国');
  • 关于URL编码

    • URL编码是一种浏览器用来打包表单输入的格式,浏览器从表单中获取所有的name和其对应的value,将他们以name/value编码方式作为URL的一部分或者分离的发送到服务器上。在 ajax 中要手动设置 Content-Type 为 application/x-www-form-urlencoded。
    • URL编码规则:每对name/value由&分开,每对来自表单的name/value用=分开。如果用户没有输入值的那个name依旧会出现不过就是没有值。URL编码是在字符ASCII码的十六进制数的前面加上%。例如:中国 被转成了 %E4%B8%AD%E5%9B%BD

onload 事件

在ajax请求操作完成后触发, 触发时机在 readyState==4 状态之后,这时候返回的内容已全部接受。

xhr.onload = function(){
  var s = xhr.status;
  if((s >= 200 && s < 300) || s == 304){
    var resp = xhr.responseText;
    //TODO ...
  }
}

onreadystatechange 事件

在readystate记录的状态改变时触发。onreadystatechange 方法会被触发4次。通常在事件处理函数中判断 readystate 为4的情况下,才算全部接受到内容。

xhr.onreadystatechange = function(e){
  if(xhr.readyState==4){
    var s = xhr.status;
    if((s >= 200 && s < 300) || s == 304){
      var resp = xhr.responseText;
      //TODO ...
    }
  }
}

以上是对Ajax知识点的总结,如有问题,欢迎指正!

扩展阅读:

https://xhr.spec.whatwg.org/#states

http://www.ruanyifeng.com/blog/2010/02/url_encoding.html

https://imququ.com/post/four-ways-to-post-data-in-http.html

原文链接:https://segmentfault.com/a/1190000015606826

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-35788.html

文章标题:Ajax 知识点的那些事

相关文章
12个你未必知道的CSS小知识
虽然CSS并不是一种很复杂的技术,但就算你是一个使用CSS多年的高手,仍然会有很多CSS用法/属性/属性值你从来没使用过,甚至从来没听说过。 1.CSS的color属性并非只能用于文本显示 对于CSS的color属性,相信所有Web开发人员...
2015-11-12
ajax为什么令人惊异?ajax的优缺点
使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。 Ajax不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。就像DHT...
2015-11-12
HTML5的5个不错的开发工具推荐
HTML5规范终于在今年正式定稿,对于从事多年HTML5开发的人员来说绝对是一个重大新闻。数字天堂董事长,DCloud CEO王安也发表了文章,从开发者和用户两个角度分析了HTML对两个人群的优势。其实,关于HTML5的开发工具,我们以往的...
2015-11-12
JavaScript教程:JS中的原型
Keith Peters 几年前发表的一篇博文,关于学习没有“new”的世界,其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法(The Standard Way) 一直以来,我们学习的在 JavaScript 里创建对...
2015-11-12
AJAX的浏览器支持
AJAX 的要点是 XMLHttpRequest 对象。 不同的浏览器创建 XMLHttpRequest 对象的方法是有差异的。 IE 浏览器使用 ActiveXObject,而其他的浏览器使用名为 XMLHttpRequest 的 Jav...
2015-11-12
Riot.js:不足1KB的MVP客户端框架
Riot.js是一款MVP(模型-视图-呈现)开源客户端框架,其最大的特点就是体积非常小,不足1KB,虽然体积小,但它可以帮助用户构建大规模的Web应用程序。 Riot.js是由Moot公司开发,目前最新版本为v0.9.2,遵循MIT开源许...
2016-03-11
typeof、instanceof和contructor的区别
typeof:以字符串的形式返回变量的原始类型,typeof在两种情况下会返回&quot;undefined&quot;:一个变量没有被声明的时候,和一个变量的值是undefined的时候,注意,typeof null也会返回object,...
2015-11-12
JavaScript的组成
一个完整的JavaScript由3个部分组成:核心(ECMAScript) 文档对象模型(DOM) 浏览器对象模型(BOM) ECMAScript 描述了该语言的语法和基本对象 ; DOM 描述了处理网页内容的方法和接口 ; BOM 描...
2015-11-12
JavaScript 事件流、事件处理程序及事件对象总结
JS与HTML之间的交互通过事件实现。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用监听器(或处理程序)来预定事件,以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察员模式,支持页面的行为与页面的外观之间的松散耦合。...
2017-04-05
必须记住的 30 类 CSS 选择器
开篇 有 30 个 CSS 选择器你必须烂熟于心,它们适应于当今各大主流浏览器。 1.* * { margin: 0; padding: 0; } *选择器选择的是每一个单一元素。很多程序员用上面的 CSS 将所有元素的 ma...
2015-11-16
回到顶部