Ajax介绍
AJAX是异步的JavaScript和XML(Asynchronous JavaScript And XML)。简单点说,就是使用浏览器内置对象 XMLHttpRequest
与服务器通信。
可以使用JSON,XML,HTML和text文本等格式发送和接收数据。
Ajax的应用场景
搜索建议提示
地图
验证用户名是否存在
网页聊天室
无刷新的分页
总之,在不刷新页面的情况下,还要完成页面和服务器的数据交互,都可以使用Ajax
GET和POST请求方式
当使用浏览器和服务器进行数据交互时,多数都是由浏览器端发起请求,然后才能获取响应结果。
浏览器能够发起的请求,又分为多种请求方式,但常用的请求方式只有下面两种:
GET ,获取;如果向服务器发送请求,获取服务器的资源,使用GET方式
比如获取页面中需要的数据
比如获取一个用户的信息(用户名、昵称、头像等)
POST,邮寄(提交)。如果提交数据给服务器,那么使用POST方式。
比如,登录、注册(提交账号和密码给服务器)
比如,添加评论,发布评论
常用请求方式的区别
GET
GET方法请求一个指定资源的表示形式. 使用GET的请求应该只被用于获取数据。
POST
POST方法用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用。
XMLHttpRequest对象简介
XMLHttpRequest
是一个内建的浏览器对象,Ajax技术的核心就是XMLHttpRequest
对象。
实现Ajax的GET请求
// 1. 创建xhr对象
var xhr = new XMLHttpRequest();
// 2. 注册 xhr.onreadystatechange 事件,当Ajax请求**成功**后,会触发onload函数。在 readystatechange 函数中,接收响应结果。
xhr.onreadystatechange = function () {
// 使用 xhr.response 接收响应结果
var res = xhr.responseText;
}
// 3. 调用open方法,设置请求方式及请求的url地址
// xhr.open('GET', 'url地址');
xhr.open('GET', 'url地址');
// 4. 最后,调用send方法,发送这次ajax请求
xhr.send();
实现Ajax的POST请求
// 1. 创建xhr对象
var xhr = new XMLHttpRequest();
// 2. 注册 xhr.onreadystatechange 事件,当Ajax请求**成功**后,会触发onload函数。在 readystatechange 函数中,接收响应结果。
xhr.onreadystatechange = function () {
// 使用 xhr.response 接收响应结果
var res = xhr.responseText;
}
// 3. 调用open方法,设置请求方式及请求的url地址
xhr.open('POST', 'url地址');
// 4. 调用setRequestHeader,设置请求头,目的是告知服务器以何种方式解析请求体
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 5. 最后,调用send方法,发送这次ajax请求
xhr.send('bookname=西游记&author=唐僧&publisher=大唐出版社');
Content-Type
这里设置的 Content-Type
,作用是告知服务器,浏览器提交的数据是何种类型的。
application/x-www-form-urlencoded(需要自己指定) ,表示客户端提交的是查询字符串。
application/json(需要自己指定) ,表示客户端提交的是 JSON 字符串。
multipart/form-data(xhr对象会自动设置),表示客户端提交的是 FormData 对象。
什么是URL编码?
把中文和部分特殊符号转成 URL的标准格式 ,这就是url编码
如,把“中文” 进行url编码后得到 “%E4%B8%AD%E6%96%87”
为什么要对请求参数进行编码
RFC文档规定,只有字母和数字[0-9a-zA-Z]、一些特殊符号“$-_.+!*’(),”[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL
对于Unicode字符,RFC文档建议使用utf-8对其进行编码得到相应的字节,然后对每个字节执行百分号编码,也就是所谓的 URL编码。
编码能够解决的问题
乱码问题(浏览器使用utf-8、服务器使用其他编码,传输数据的时候,就会乱码)
提交的内容有特殊符号问题,比如添加一本书,书名是 “红&黑”
如何进行URL编码
编码:encodeURIComponent('西游记')
解码:decodeURIComponent("%E8%A5%BF%E6%B8%B8%E8%AE%B0");
readyState属性
Ajax从创建xhr对象开始,一直到完全接收服务器返回的结果为止;我们可以把整个请求响应过程划分为5个阶段。并且可以使用 xhr.readyState 属性检测当前请求执行到哪个阶段了。
readyState属性值为一个数字,不同的数字表示Ajax的不同状态。
如果状态值为0(xhr.readyState === 0),初始状态,表示xhr对象一定创建了
如果状态值为1(xhr.readyState === 1),表示open调用了
如果状态值为2(xhr.readyState === 2),表示send一定调用了,并且已经接收到响应头。
如果状态值为3(xhr.readyState === 3),表示正在接收服务器返回的数据(可能已接收完毕,也可能正在接收中,取决于数据量的大小)
如果状态值为4
(xhr.readyState === 4
),表示Ajax请求~响应过程完成
// 1. 创建xhr对象
var xhr = new XMLHttpRequest();
console.log(xhr.readyState); // ===> 0
// 2. 注册 xhr.onreadystatechange 事件,当Ajax请求**成功**后,会触发onload函数。在 readystatechange 函数中,接收响应结果。
xhr.onreadystatechange = function () {
console.log(xhr.readyState); // ===> 4
// 使用 xhr.response 接收响应结果
var res = xhr.responseText;
}
// 3. 调用open方法,设置请求方式及请求的url地址
// xhr.open('GET', 'url地址');
xhr.open('GET', 'url地址');
// 4. 最后,调用send方法,发送这次ajax请求
xhr.send();
onreadystatechange事件
onreadystatechange 翻译过来是 当Ajax的请求状态改变的时候。
所以,它是配合上述的 readyState 使用的事件。
onload有浏览器兼容问题,如果你的项目需要支持低版本的浏览器,那么可以使用 onreadystatechange事件代替onload事件。
由于onreadystatechange事件可能会触发多次,所以需要在事件中加入判断,已保证准确的接收到响应结果。
// 1. 创建xhr对象
var xhr = new XMLHttpRequest();
// IE6 创建对象 var xhr = new ActiveXObject('Microsoft.XMLHTTP');
// 2. 使用onreadystatechange代替onload
xhr.onreadystatechange = function () {
// 判断Ajax请求是否完成
if(xhr.readyState === 4) {
// 还要根据响应状态码判断,请求是否成功
if (xhr.status === 200) {
console.log(xhr.responseText);
} else {
console.log('请求失败')
}
}
}
// 3. 调用open方法,设置请求方式及请求的url地址
// xhr.open('GET', 'url地址');
xhr.open('GET', 'url地址');
// 4. 最后,调用send方法,发送这次ajax请求
xhr.send();
封装Ajax
/**
* 把字面量对象转换成查询字符串
* @param {object} obj 一个字面量对象
* @returns {string} 查询字符串
*/
function ObjectToQueryString(obj) {
var arr = [];
for (var key in obj) {
arr.push(`${key}=${obj[key]}`);
}
return arr.join('&');
}
/**
* 实现Ajax请求
* @param {object} option 对象形式的参数
* @param {string} option.type 请求方式
* @param {string} option.url 接口地址
* @param {object} option.data 请求参数
* @param {callback} option.success 成功后的回调
*/
function ajax(option) {
// 1. 把请求方式统一转大写,为后面的判断做准备
var type = option.type.toUpperCase();
// 2. 调用上面的函数,把请求参数处理成查询字符串
var params = ObjectToQueryString(option.data);
// 3. 写Ajax的基本步骤
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
// 当响应成功后,把JSON格式的结果转换为JS对象
var res = JSON.parse(this.responseText);
// 把结果,传递给 success 回调函数
option.success(res);
}
}
// 判断是GET还是POST请求方式
if (type === 'GET') {
xhr.open('GET', option.url + '?' + params);
xhr.send();
} else if (type === 'POST') {
xhr.open('POST', option.url);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(params);
}
}