【Web全栈课程5】自己封装一个简单的ajax
ajax
ajax内部怎么实现的?
使用一个php文件来模拟服务器返回,php代码如下
<?php echo $_GET['a']+$_GET['b']; ?>
请求的发送实际上我们都通过浏览器的XMLHttpRequest实现,ie6使用ActiveXObject,不考虑IE6的兼容,我们实现一个简单的xhr请求如下。
<html>
<meta charset="utf-8">
<head></head>
<script>
window.onload=function(){
let oBtn=document.getElementById('btn1');
oBtn.onclick = function(){
let xhr=new XMLHttpRequest(); // 不兼容ie6
// 连接,true代表异步,false代表同步;浏览器对异步的xhr会报错
xhr.open('get','../server/a.php',true,);
// 发送;send里面是body,post需要发送header
xhr.send();
// 接收;4代表结束
xhr.onreadystatechange = function(){
console.log(xhr.readyState);
};
};
};
</script>
<body>
<input type="button" value="提交" id="btn1">
</body>
</html>xhr.readyState状态值
0:刚刚创建初始状态 1:已连接 2:已发送 3:已接受-头(32k上限) 4:已接受-body(1G上限)
http状态码
1XX 消息
2XX 成功
3XX 重定向
301 永久重定向——浏览器永远不会再次请求老的地址
302 临时重定向——浏览器下次还会请求老地址
304 (not modified)重定向到缓存请求——因此304也是成功
4XX 请求错误,客户端错误
5XX 服务端错误
6XX 扩展错误码因此可以通过2XX和304的状态码判断请求成功。
// 接收;4代表结束
xhr.onreadystatechange = function(){
if (xhr.readyState ==4){
if ((xhr.status>=200&&xhr.status<300)||xhr.status==304){
alert('成功:'+xhr.responseText);
console.log(xhr);
} else {
alert('失败');
}
}
};xhr返回值
xhr.responseText 文本数据
xhr.responseXML XML数据(已经不常用)
xml数据是不固定标签组成的数据,xml数据更加占空间,例如:
<person>
<name>xiaoyezi</name>
<age>18</age>
<job>front engineer</job>
</person>json格式:
let json={name:'xiaoyezi',age:18,job:'front engineer'};XMLHttpRequest发送POST请求
按照我们上面代码的思路,post请求的写法推导出来应该是如下写法,实际上如下写法并不行。
// 连接,true代表异步,false代表同步;浏览器对异步的xhr会报错
xhr.open('post','../server/a.php',true,);
// 发送;send里面是body,post需要发送
xhr.send('a=12&b=5');对比form的post提交方式,我们可以看到,Request Headers里面有条设置和form提交的不同:
Content-Type: text/plain;charset=UTF-8 form提交:Content-Type: application/x-www-form-urlencoded
需要增加setRequestHeader的设置,再send请求的body内容,请求成功。
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send('a=12&b=5');content-type类型及含义?
text/plain 文本 application/x-www-form-urlencoded &&&连接的方式,eg:a=12&b=5 multippart/form-data 定界符分割各个数据(文件上传)
实现简单的自定义ajax
function ajax(options){
// 数据处理
options = options || {};
options.data = options.data || {};
options.type = options.type || 'get';
options.dataType = options.dataType || 'text'; //解析数据
let arr = [];
for (let name in options.data) {
arr.push(`${name}=${encodeURIComponent(options.data[name])}`);
}
let dataStr = arr.join('&');
// 不兼容ie6
let xhr=new XMLHttpRequest();
// 连接,true代表异步,false代表同步;浏览器对异步的xhr会报错
if (options.type == 'get'){
xhr.open('get',options.url + '?' + dataStr,true);
xhr.send();
} else {
xhr.open('post',options.url,true,);
// 发送;send里面是body,post需要发送Content-Type
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send(dataStr);
}
// 接收;4代表结束
xhr.onreadystatechange = function(){
if (xhr.readyState ==4){
if ((xhr.status>=200&&xhr.status<300)||xhr.status==304){
let result = xhr.responseText;
switch (options.dataType){
case 'text':
break;
case 'json':
if (window.JSON && JSON.parse){
result = JSON.parse(result);
} else {
result = eval("("+result+")");
}
break;
case 'xml':
result = xhr.XMLHttpRequest;
break;
default:
break;
}
options.success && options.success(result);
} else {
options.error && options.error('error');
}
}
};
} 相关推荐
kentrl 2020-11-10
结束数据方法的参数,该如何定义?-- 集合为自定义实体类中的结合属性,有几个实体类,改变下标就行了。<input id="add" type="button" value="新增visitor&quo
ajaxyan 2020-11-09
zndy0 2020-11-03
学留痕 2020-09-20
learningever 2020-09-19
chongxiaocheng 2020-08-16
ajaxhe 2020-08-16
lyqdanang 2020-08-16
curiousL 2020-08-03
时光如瑾雨微凉 2020-07-19
坚持着执着 2020-07-16
jiaguoquan00 2020-07-07
李永毅 2020-07-05
坚持着执着 2020-07-05