摘要:发送后等待服务端响应,响应是以触发事件来通知,随后通过请求对象实例拿到状态以及响应的内容。表示服务器响应内容的文本形式。而是在调用发出后,被调用者通过触发事件,调用事件处理回调函数。
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更加普遍。
关于JSONJSON(JavaScript Object Notation) 是一种轻级的数据交换格式。JSON实际上是JavaScript的一个子集。但是和JavaScript的语法稍微有些不同,有属于JSON自己的语法。
JSON构建于两种形式:
无序的“‘名称/值’对”集合
一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
值的有序列表
一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
在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字符串。简单来说 JSON 是 JavaScript 对象的字符串表示法,它使用文本表示一个 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 | 请求操作已经完成,响应的内容全部接受完成 |
两个都是只读属性,存的是服务器的响应内容。 responseText表示服务器响应内容的文本形式。
responseType 属性可读可写属性,xhr.responseType 表示响应的类型, 缺省为空字符串, 可取 "arraybuffer" , "blob" , "document" , "json" , and "text" 共五种类型。
当将responseType设置为一个特定的类型时,你需要确保服务器所返回的类型和你所设置的返回值类型是兼容的。那么如果两者类型不兼容,服务器返回的数据变成了null,即使服务器返回了数据。还有一个要注意的是,给一个同步请求设置responseType会抛出一个InvalidAccessError 的异常。
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知识点的总结,如有问题,欢迎指正!
扩展阅读:
readyState状态描述
https://xhr.spec.whatwg.org/#states
关于URL编码
http://www.ruanyifeng.com/blog/2010/02/url_encoding.html
四种常见的 POST 提交数据方式:
https://imququ.com/post/four-ways-to-post-data-in-http.html
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/96063.html
摘要:异常处理异常处理一直是回调的难题,而提供了非常方便的方法在一次调用中,任何的环节发生,都可以在最终的中捕获到错误处理基本的小结具体的很多的用法可以参考阮一峰的入门教程,还有就是上面提到的电子书。 JS异步那些事 一 (基础知识)JS异步那些事 二 (分布式事件)JS异步那些事 三 (Promise)JS异步那些事 四(HTML 5 Web Workers)JS异步那些事 五 (异步脚本...
摘要:异步那些事一基础知识异步那些事二分布式事件异步那些事三异步那些事四异步那些事五异步脚本加载事件概念异步回调首先了讲讲中两个方法和定义和用法方法用于在指定的毫秒数后调用函数或计算表达式。功能在事件循环的下一次循环中调用回调函数。 JS异步那些事 一 (基础知识)JS异步那些事 二 (分布式事件)JS异步那些事 三 (Promise)JS异步那些事 四(HTML 5 Web Workers...
阅读 1469·2023-04-26 00:20
阅读 886·2023-04-25 21:49
阅读 789·2021-09-22 15:52
阅读 562·2021-09-07 10:16
阅读 946·2021-08-18 10:22
阅读 2635·2019-08-30 14:07
阅读 2218·2019-08-30 14:00
阅读 2625·2019-08-30 13:00