[关闭]
@wy 2018-07-12T16:49:48.000000Z 字数 6709 阅读 437

Ajax 知识点的那些事

javascript


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中值支持以下几种数据类型:

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

JSON 对象

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

JSON.stringify()

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

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

例如在 JavaScript 中定义的对象:

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

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

  1. 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 函数时候,就发起了一个异步操作,此时不会立马得到反馈,而到了设置的时间,会调用传入的回调函数,一旦回调函数执行就得到通知说明异步完成了。

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

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

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

  1. var arr = [1,2,3,4,5,6,7,8];
  2. arr.map((item) => {
  3. return item * 2
  4. })
  5. arr.forEach((item) => {
  6. return item * 2
  7. })

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

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

分解Ajax中的知识点

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

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

  1. let xhr = new XMLHttpRequest;
  2. console.log(xhr.readyState); // 0 UNSENT 创建实例对象,尚未调用open();
  3. xhr.open('GET','http://kuapi.wykiss.cn/api?json=true',true);
  4. console.log(xhr.readyState); // 1 OPENED open()方法已成功调用。
  5. // 当readyState状态发生变化时,触发此事件
  6. xhr.onreadystatechange = function () {
  7. console.log(xhr.readyState);
  8. if(xhr.readyState === 2){ // 2 HEADERS_RECEIVED 可以获取到响应头信息
  9. console.log('响应头信息为:',xhr.getAllResponseHeaders())
  10. }else if(xhr.readyState === 3){ // 3 LOADING 正在接收部分响应内容
  11. console.log('接收的部分内容是:',xhr.response)
  12. }else if(xhr.readyState === 4) { // 4 DONE 请求操作已经完成,响应的内容全部接受完成
  13. console.log('接收全部内容是:',xhr.response)
  14. }
  15. }
  16. // 请求操作完成 触发的事件
  17. xhr.onload = function () {
  18. console.log('请求操作完成,触发此事件')
  19. console.log('可以直接获取响应的全部内容',xhr.response)
  20. }
  21. 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)

send() 方法

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

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

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

  1. xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
  2. xhr.send('json=true&country=中国');

onload 事件

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

  1. xhr.onload = function(){
  2. var s = xhr.status;
  3. if((s >= 200 && s < 300) || s == 304){
  4. var resp = xhr.responseText;
  5. //TODO ...
  6. }
  7. }

onreadystatechange 事件

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

  1. xhr.onreadystatechange = function(e){
  2. if(xhr.readyState==4){
  3. var s = xhr.status;
  4. if((s >= 200 && s < 300) || s == 304){
  5. var resp = xhr.responseText;
  6. //TODO ...
  7. }
  8. }
  9. }

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

扩展阅读:

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注