在使用ajax进行请求时,基本上都是四步骤:
1、创建ajax对象
2、配置ajax对象(以什么方式进行请求,向哪个地址发送请求)
3、发送请求
4、接收到相应数据后的事件处理
为了避免不同的请求需要写同样的代码,造成了代码的冗余。
现在对ajax请求进行封装,需要时调用传参即可:
初级函数封装
<body>
<script>
//创建ajax函数
function ajax(options) {
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 配置ajax对象
xhr.open(options.type, options.url);
// 发送请求
xhr.send();
// 监听xhr的onload事件,当xhr对象接收完响应数据后触发
xhr.onload = function() {
options.success(xhr.responseText);
}
}
//调用封装的ajax函数
ajax({
// type代表请求方式
type: 'get',
// url代表请求地址
url: 'http://localhost:3000/first',
// 要执行的函数
success: function(data) {
console.log('服务器端的响应结果是:' + data);
}
})
</script>
</body>
函数封装改造升级
升级之处如下:
1、设置默认值:
默认的请求方式(没有指明则默认get)
默认的请求地址 url:‘’
默认的请求参数 data:{}
默认的请求头(没有指明则默认的普通请求头类型application/x-www-form-urlencoded)
success()函数、error()函数
2、assign做对象覆盖:Object.assign(obj1,obj2)
两个对象中一方不存在的属性,以另一方为主;双方都存在的属性,以第二个参数的为主
最后将结合后的数据存于 第一个参数obj1中
用于 默认值 和 传入的对象实参 进行互补更新,更新后的数据存储在默认值中
3、对请求参数进行处理
将对象类型转为字符串类型,同 & 进行拼接
如果是 get 请求方式:将拼接好的字符串类型的参数和请求地址进行拼接
注意:字符串的拼接和切割的使用(str.substr(n,m)包前不包后)
4、配置ajax对象(请求方式,请求地址)
如果是get请求方式,上面也已经将请求参数加到请求地址上,直接传参即可
如果是post请求方式,上面也不会将请求参数和请求地址进行拼接,也可直接传参
5、判断请求方式以便进行请求发送
如果是post请求方式,需要分流处理(普通类型 or json类型)---请求参数类型
post请求方式的话,请求参数需要传入send()中,但是需要是字符串类型
所以这里判断是否是json类型,如果是,那么就要转为字符串类型再传入
否则直接传入
如果是get请求方式,无需判断参数类型,也无需传入参数,直接send()发送请求
6、onload事件中判断服务器端响应的数据类型(普通类型 or json类型)---响应数据类型
Ajax对象的getResponseHeader('Content-Type')获取服务器端的响应头数据
如果包含“application/json”则表示响应数据是json类型
由于responseText获取到的是字符串类型,所以需要将相应数据再转换为对象类型
否则普通类型无需转换
7、onload事件中判断状态码
http状态码为200时表示正常响应,此时再调用success()函数
因为onload的调用不一定能保证没有错误,但是状态码为200可以说明正常
<body>
<script>
function ajax(options) {
// 设置默认值
var defaults = {
type: 'get',
url: '',
data: {},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function() {},
error: function() {}
};
// assign:对象覆盖,会修改原有对象,将options的值覆盖给defaults
Object.assign(defaults, options);
// 创建ajax对象
var xhr = new XMLHttpRequest();
var params = '';
// 对请求参数的变量进行处理(将对象转为字符串)
for (var attr in defaults.data) {
params += attr + '=' + defaults.data[attr] + '&';
// 注意attr是变量,不是固定的属性,所以不能直接data.attr,应该换成中括号
}
// 将参数后的&截取掉,包前不包后
params = params.substr(0, params.length - 1);
// 将请求参数和请求地址进行拼接
if (defaults.type == 'get') {
defaults.url = defaults.url + '?' + params;
}
// 配置ajax对象(如果是get请求方式,上面已经做出来地址和参数的拼接)
// 如果是post请求方式,不会进行拼接,这里也就只是地址了
xhr.open(defaults.type, defaults.url);
// 处理发送请求,post需要传入参数,get不用,所以要分流处理
if (defaults.type == 'post') {
var contentType = defaults.header['Content-Type']
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Content-Type', contentType);
if (contentType == 'application/json') {
// 如果是json的话就要将json类型转为字符串,因为请求发送中只能是字符串
xhr.send(JSON.stringify(defaults.data))
} else {
// 如果是普通类型就直接将处理后的data传递到send中
xhr.send(params);
}
} else {
xhr.send();
}
// 监听xhr的onload事件,当xhr对象接收完响应数据后触发
xhr.onload = function() {
var contentType = xhr.getResponseHeader('Content-Type');
var responseText = xhr.responseText;
if (contentType.includes('application/json')) {
// 将json字符串转换为json对象
responseText = JSON.parse(responseText);
} else {
console.log('普通类型');
}
if (xhr.status == 200) {
defaults.success(responseText, xhr);
} else {
// 将xhr返回,可以查看内部信息
defaults.error(responseText, xhr);
}
}
}
//传参调用ajax()函数
ajax({
url: 'http://localhost:3000/responseData1',
data: {
name: '昔冰',
age: 20,
msg: '积善者必有余庆'
},
success: function(data, xhr) {
console.log('服务器端的响应结果是:');
console.log(data);
},
error: function(data, xhr) {
console.log('这里是error');
console.log(data);
console.log(xhr);
}
})
</script>
</body>