Ajax
:Asynchronous JavaScript and XML(异步JavaScript和XML)。
是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。
功能
:节省用户操作时间,提高用户体验,局部刷新减少数据请求;
我们要知道,其实Ajax就是去请求后台接口拿数据的,前端拿到后台的数据后就用这些数据进行dom操作以相应的样式输出到页面中。(最难的地方就是对获取到的数据进行分析和处理并渲染到页面上)
一、我们首先来看一个get请求的ajax流程(js代码):
//创建一个ajax对象(类似于打开浏览器)
var xhr = XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject('Microsoft.XMLHTTP'); //new ActiveXObject('Microsoft.XMLHTTP') 这个我们是对低版本IE浏览器进行兼容性处理
//使用ajax对象下面的open方法告知浏览器请求的方式(相当于在地址栏输入地址)
xhr.open('get','1.txt',true);
//提交(相当于按回车键)
xhr.send(); //在这一步才会发送网络请求(上面是准备工作)
//等待服务器返回内容
xhr.onreadystatechange = function() { // 监测readyState状态值变化
if ( xhr.readyState == 4 ) { // readyState状态值为4表示响应内容解析完成,可以在客户端调用了
if ( xhr.status == 200) { //200表示http请求正确
alert( xhr.responseText ); // responseText 为后台返回的数据
} else {
alert('出错了,Err:' + xhr.status); //返回错误响应的http状态码
}
}
}
二、接下来我们详细分析一下请求ajax的流程:
1、创建一个ajax对象
var xhr = new XMLHttpRequest();
(创建了ajax对象之后才能使用ajax对象下面的方法和属性)
2、使用ajax对象下面的open()方法
open('get','url',true)方法
接收三个参数:
1.请求方式(get、post 或者其他)
2.地址(请求的后台接口地址)
3.是否异步(true为异步;false为同步)
异步
:非阻塞 ajax请求的代码不会影响后面代码的执行(ajax请求的代码就算没执行完也能执行后面的代码)
同步
:阻塞 ajax请求的代码会影响后面代码的执行(ajax请求的关联的代码一定要执行完才能继续执行后面的代码)
(1)、get请求方式
get请求方式是通过
url?
后面的参数值传送的(根据后端提供的接口请求参数来传入传输的,多个参数之间用&连接)(格式要正确填写)
(ajax参数的格式都是
参数名1=参数值1&参数名2=参数值2....
)
注意:get请求存在如下两个问题
1.
会缓存
(其实我们后台数据已经变了,我们希望在刷新地址栏的时候,页面数据会变动。但是因为get请求方式地址不改变,内容就不会变。) 这时我们需要在url?后面连接一个随机数,时间戳
new Date().getTime()
(这样就每一次访问的都是不一样的地址)
2.
中文会出现乱码
用编码
encodeURI()
解决
如:
xhr.open('get','get.php?username='+encodeURI('刘伟')+'&age=30&' + new Date().getTime(),true);
(2)、post请求方式
请求数据的参数是在请求头中(那么数据就不能直接在url后面传入参数了)。
xhr.open('post','post.php',true);
//一定要申明发送的数据类型(ajax没有默认的编码方式,表单提交有)
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
//post请求方式,数据放在send()里面作为参数传递
xhr.send('username=刘伟&age=30');
注意
:post没有缓存问题(无需设置时间戳),也不会有出现中文乱码问题(无需编码)
3、使用ajax对象下面的send()方法
向服务器发送请求。
(1)、get方式,无需传入参数
xhr.send()
(2)、post方式,需要传入后台需要的参数
xhr.send(‘多个参数使用&分隔’)
4、等待服务器响应并返回数据
下面介绍ajax对象下面的属性,当有它们的值有相关变化时,说明服务器有相关的响应了。
readyState
: ajax工作状态(有五个值)
0 (初始化)还没有调用open()方法
1 (载入)已调用send()方法,正在发送请求
2 (载入完成)send()方法完成,已收到全部响应内容
3 (解析)正在解析响应内容
4 (完成)响应内容解析完成,可以在客户端调用了
onreadystatechange
: 当readyState改变的时候触发(可能会触发很多次)
responseText
: ajax请求返回的数据内容就被存放到这个属性下面(通过调用这个属性就能获取到返回的内容,均为字符串格式)
status
: 服务器状态,http状态码(容错处理)
http状态码:
1xx:指示信息——表示请求已接收,继续处理
2xx:成功——表示请求已经被成功接收
3xx:重定向——要完成的请求必须进行进一步操作
4xx:客户端错误——请求有语法错误或者请求无法实现
5xx:服务器错误——服务器未能实现合法的请求
三、jq和 js的完整请求方式(只介绍常用的语法)
我们都知道在jquery中使用ajax很方便,因为已经帮我们封装好了。
1、jquery使用ajax:
$.ajax({
url : '请求的接口地址url',
data : '需要传给后台的参数',
type : 'post', //默认是get
dataType:"json", // 预期服务器返回的数据类型,默认为json
success : function(data){ //成功获取数据后的回调函数
// data为后台返回的数据,通过处理data数据来渲染页面
},
error : function(err){ //获取数据失败后的回调函数
// err 为后台请求错误后返回的错误信息
console.log(err)
}
});
2、javascript封装ajax(只封装了get和post请求方式),使得像jquery的使用方式
//封装实参覆盖形参的函数
function extend(obj1, obj2) {
for (var attr in obj2) {
obj1[attr] = obj2[attr];
}
}
// 将data中传入的json对象转为name=winne&age=18&like={"jk":2}&arr=[1,2]这种格式
function paramData (json) {
let str = ''
for (let key in json) {
if (typeof json[key] === 'object') {
str += `${key}=${JSON.stringify(json[key])}&`
}else{
str += `${key}=${json[key]}&`
}
}
return str.substring(0, str.length - 1)
// 上面的代码可以用下面的代码代替
// let resultStr = Object.keys(json).map( (key) => {
// let value = json[key]
// if (typeof value === 'object') {
// value = JSON.stringify(value)
// }
// return `${key}=${value}`
// }).join('&')
// return resultStr
}
function ajax(opt) {
defaultOpt = { //默认函数参数
"method":'get', //默认为get传输
"data":'', //默认没有参数
"url":'',
"dataType":"json", //默认返回json类型的数据
"success": function(data){}, //默认获取到数据后什么都不做
"error":function(err){}
},
extend(defaultOpt, opt); //配置参数赋值给默认参数
// 创建一个支持ajax的对象
var xhr = XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject('Microsoft.XMLHTTP');
if (defaultOpt.method == 'get' && defaultOpt.data) { //调用默认参数
defaultOpt.url += '?' + paramData(defaultOpt.data); //get请求的完整url拼接
}
xhr.open(defaultOpt.method.toLowerCase() , defaultOpt.url, true);
if (defaultOpt.method.toLowerCase() == 'get') {
xhr.send();
} else if(defaultOpt.method.toLowerCase() == 'post'){
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.send(paramData(defaultOpt.data));
}
//等待服务器响应并返回数据
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
defaultOpt.success && defaultOpt.success(xhr.responseText); //可变的地方用参数传入,代码块就用函数传入
} else {
defaultOpt.error&& defaultOpt.error(xhr);
// console.log('出错了' + xhr);
}
}
}
}
// 调用js封装好后的ajax
ajax({
url : '请求的接口地址url',
data : { // 传给后台的参数
name: 'winne',
age: 18,
like: {jk: 2},
arr: [1, 2]
},
type : 'post', //默认是get
success : function(data){ //成功获取数据后的回调函数
// data为后台返回的数据,通过处理data数据来渲染页面
// 我们最常用的是JSON.parse(data)来把字符串json转化为真正的json来进行数据处理;
// 使用 JSON.stringfy(json)来把json数据转化为json字符串
},
error : function(err){ //获取数据失败后的回调函数
// err 为后台请求错误后返回的错误信息
console.log(err)
}
})