Ajax学习第三天
今天主要围绕以下两个问题解决:
1. 低版本IE浏览器的缓存问题
解决方案:在请求地址的后面加上请求参数,保证每一次请求中的请求参数的值不相同即可。
xhr.open('get','http://www.example.com?t='+Math.random());
2. 发送一次请求代码过多,发送多次请求代码冗余且重复
解决方案:将请求代码封装到函数中,发请求时调用函数即可。封装Ajax代码如下:
<body>
<script>
function ajax(options) {
//存储的是默认值
var defaults = {
type: 'get',
url: '',
data: '',
header: {
'Content-Type': 'application/json'
},
success: function () { },
error: function () { }
};
//对象覆盖 使用options对象中的属性覆盖defaults对象中的属性
Object.assign(defaults, options);
//创建Ajax对象
var xhr = new XMLHttpRequest();
//定义需要拼接的字符串
var params = "";
//循环对象
for (var attr in defaults.data) {
//将参数转换为字符串
params = params + attr + '=' + defaults.data[attr] + "&";
}
//将最后一个&截取掉 得到完整的拼接的字符串
params = params.substring(0, params.length - 1);
//1.为get方式 2.为post方式
if (defaults.type == 'get') {
//指明请求方式及请求路径
xhr.open(defaults.type, defaults.url + '?' + params);
xhr.send();
} else if (defaults.type == 'post') {
//指明请求方式及请求路径
xhr.open(defaults.type, options.url);
//判断请求报文头的类型
var contentType = defaults.header['Content-Type'];
//设置请求报文头的类型
xhr.setRequestHeader('Content-Type', contentType);
//1.application/x-www-form-urlencoded类型
//2.application/json类型
if (contentType == 'application/x-www-form-urlencoded') {
xhr.send(params);
} else if (contentType == 'application/json') {
xhr.send(JSON.stringify(defaults.data));
}
}
//服务器端响应
xhr.onload = function () {
//得到服务器返回的类型
var contentType = xhr.getResponseHeader('Content-Type');
//服务器端返回的数据
var responseText = xhr.responseText;
//若为json类型
if (contentType.includes('application/json')) {
//转换为json对象 便于使用
responseText = JSON.parse(responseText);
}
//判断http状态码等于200为正常
if (xhr.status == 200) {
//请求成功 调用success函数
defaults.success(responseText, xhr);
} else {
//请求失败 调用error函数
defaults.error(responseText, xhr);
}
}
}
ajax({
type: 'post',
url: 'http//localhost/Ajax封装.html',
data: { name: 'zhangSan', age: 20 },
header: {
'Content-Type': 'application/json'
},
success: function (data, xhr) {
console.log(data);
console.log(xhr);
},
error: function (data, xhr) {
console.log(data);
console.log(xhr);
}
});
/*
请求参数要考虑的问题
1.请求参数位置的问题
将请求参数传递到Ajax函数内部,在函数内部根据请求方式的
不同将请求参数放置在不同位置
get 放在请求地址的后面
post 放在send()中
2.请求参数格式的问题
application/x-www-form-urlencoded
参数名称 = 参数值 & 参数名称 =参数值
name = zhangSan & age = 20
application/json
{name:'zhangSan',age: 20}
1.传递对象数据类型对于函数的调用者更加友好
2.在函数内部对象数据类型转换为字符串数据类型更加方便
*/
</script>
</body>
大致思路总结如下:
-
封装请求类型:判断请求类型为 get / post;
-
封装请求报文头类型:application/x-www-form-urlencoded application/json
若为后者,则需要在将拼接的字符串类型转换为JSON字符串类型,使用函数JSON.stringify();
-
封装服务器端返回结果:
- 判断http状态码,使用
xhr.status
若状态码为200 则调用成功函数 若为其它,则调用错误函数。 - 一般情况下,服务器端返回JSON数据作为响应内容,但是客户端拿到的是JSON字符串,所以我们最好将JSON字符串转换为JSON对象,这样函数调用者方便修改数据。
使用函数xhr.getResponseHeader('Content-Type');
得到服务器返回的类型,若得到的是application/json类型,则将服务器返回的数据转换为JSON对象responseText = JSON.parse(responseText);
若得到text/html类型,则不做处理
- 判断http状态码,使用
-
封装用户是否传值:若用户设置相关内容,则使用用户设置的相关内容,否则使用默认值,要注意对象覆盖函数的用法!
Object.assign(defaults, options);