AJAX即“Asynchronous JavaScript and XML”(异步的JavaScript与XML技术),指的是一套综合了多项技术的浏览器端网页开发技术,包含了HTML、CSS、JavaScript、DOM、XML等技术。Aiax 只是一个哥们“发明”的缩写,这个新术语用来描述一种使用现有技术集合的一个名称。多项技术中最重要的是 XMLHttpRequest 对象,稍后会介绍到它。html
若是不使用 Ajax,仔细观察一个Form的提交,你就会发现,一旦用户点击“Submit”按钮,表单开始提交,浏览器就会刷新页面,而后会跳到新页面里告诉你操做是成功了仍是失败了。若是失败了,还要返回表单填写页,有些信息会丢失,须要从新填写,这对用户体验极其不友好。ajax
这是Web的运做原理:一次HTTP请求对应一个页面。json
若是要让用户留在当前页面中,同时发出新的HTTP请求,就必须用JavaScript发送这个新请求,接收到数据后,再用JavaScript更新页面,这样一来,用户就感受本身仍然停留在当前页面,数据却能够不断地更新。后端
也就是说,当使用了 Ajax 后,能够在不从新刷新页面的状况下与服务器通讯,交换数据,更新页面, 这样可以快速地将数据更新呈如今用户界面上,这使得程序可以更快地回应用户的操做。api
能够利用 Ajax 的特性作以下事情:数组
使用 AJAX 技术中的 XMLHttpRequest 对象与服务器通讯,交换数据。数据的格式可使用JSON,XML,HTML和文本等多种格式发送和接收。尽管X在Ajax中表明XML, 但因为JSON的许多优点,更加轻量以及是Javascript的一部分,目前JSON的使用比XML更加广泛。浏览器
JSON(JavaScript Object Notation) 是一种轻级的数据交换格式。JSON其实是JavaScript的一个子集。可是和JavaScript的语法稍微有些不一样,有属于JSON本身的语法。安全
JSON构建于两种形式:服务器
在JSON中值支持如下几种数据类型:cookie
在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 时候,发出的是一个异步请求,要经过调用函数得到响应。
使用 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 是规范制定的API,已经被现代浏览器普遍使用,它为客户端提供了在客户端和服务器之间传输数据的功能,是Ajax技术的核心所在。
全局会提供一个 XMLHttpRequest 构造函数来初始化一个请求实例对象。
var xhr = new XMLHttpRequest();
此对象上会有多个属性和方法。
只读属性,xhr.readyState 记录了请求实例对象运行过程当中所处的状态,使用数字来表示。如下是每一个数字表明的含义:
值 | 状态 | 描述 |
---|---|---|
0 | UNSENT | 请求对象已建立,还没有调用 open()方法 |
1 | OPENED | open()方法已成功调用 |
2 | HEADERS_RECEIVED | send() 方法已调用,能够获取到响应头信息 |
3 | LOADING | 正在接收部分响应内容 |
4 | DONE | 请求操做已经完成,响应的内容所有接受完成 |
两个都是只读属性,存的是服务器的响应内容。 responseText表示服务器响应内容的文本形式。
可读可写属性,xhr.responseType 表示响应的类型, 缺省为空字符串, 可取 "arraybuffer" , "blob" , "document" , "json" , and "text" 共五种类型。
当将responseType设置为一个特定的类型时,你须要确保服务器所返回的类型和你所设置的返回值类型是兼容的。那么若是二者类型不兼容,服务器返回的数据变成了null,即便服务器返回了数据。还有一个要注意的是,给一个同步请求设置responseType会抛出一个InvalidAccessError 的异常。
xhr.responseURL 返回ajax请求最终的URL, 若是请求中存在重定向, 那么responseURL表示重定向以后的URL。
只读属性。xhr.status存的是数字状态码,是标准的HTTML状态码。在请求完成前,status的值为0。若是请求出错,浏览器返回的 status 也为0。若是服务器响应中没有明确指定status码, status码将会默认为200。
只读属性。xhr.status存的是服务器返回的状态短语。这个属性包含了返回状态对应的文本信息,例如"OK"或是"Not Found"。
xhr.open() 方法初始化一个请求。
语法:
xhr.open(method, url)
xhr.open(method, url, async)
接下来讨论的是在浏览器应用层面中GET和POST发送数据的不一样。
- GET产生的URL地址能够被Bookmark,而POST不能够。 - GET请求只能进行url编码,而POST支持多种编码方式。 - GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。 - GET请求在URL中传送的参数是有长度限制的,而POST么有。 - GET比POST更不安全,由于参数直接暴露在URL上,因此不能用来传递敏感信息。 - GET参数经过URL传递,POST放在Request body中。
http://kuapi.wykiss.cn/api?js...
async 可选参数。默认为true,表示执行是否是执行异步操做。true,为异步,false,为同步。当设置false时,浏览器会出现一个警告。
// Ajax 发出异步请求 // ..... 代码省略 console.log('没获得结果,我先执行');
// Ajax 发出同步请求 // ..... 代码省略 console.log('只有同步操做完成后,我才能执行');
xhr.send() 方法用于发送 HTTP 请求。若是是异步请求(默认为异步请求),则此方法会在请求发送后当即返回,接着继续执行send后面的代码;若是是同步请求,则此方法直到服务端响应结束后所有拿到响应的数据后才会返回。
xhr.send() 方法接受一个可选的参数,其做为请求主体,发送 post 时会用到;若是请求方法是 GET,则应将请求主体设置为 null。
注意:请求方法为 post 时,要在请求头(headers)中的 Content-Type 设置消息主体编码方式,这样服务端一般是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。
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编码
在ajax请求操做完成后触发, 触发时机在 readyState==4 状态以后,这时候返回的内容已所有接受。
xhr.onload = function(){ var s = xhr.status; if((s >= 200 && s < 300) || s == 304){ var resp = xhr.responseText; //TODO ... } }
在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