如何封装一个AJAX

如何封装一个AJAX原生和promise方法

如何封装一个AJAX原生和promise方法

先来说一下什么是ajax

定义:Ajax(Asynchronous Java and XML的缩写)是一种异步请求数据的web开发技术,在不需要重新刷新页面的情况下,Ajax 通过异步请求加载后台数据,并在网页上呈现出来。

作用

提高用户体验,减少网络数据的传输量

ajax常见运用场景

表单验证是否登录成功、百度搜索下拉框提示和快递单号查询等等。

ajax原理

存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

  • 0: 请求未初始化
  • 1: 服务器连接已建立
  • 2: 请求已接收
  • 3: 请求处理中
  • 4: 请求已完成,且响应已就绪

status

200:ok
404:未找到页面
更多状态码信息见:https://highfish920.github.io/2020/08/12/状态码对应含义/

当 readyState 等于 4 且状态为 200 时,表示响应已就绪:

1
2
3
4
5
6
7
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}

get和post的区别



更多区别:https://www.cnblogs.com/logsharing/p/8448446.html

原生JS实现ajax请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<script>
function ajax(options){
options = options ||{}; //调用函数时如果options没有指定,就给它赋值{},一个空的Object
options.type=(options.type || "GET").toUpperCase();/// 请求格式GET、POST,默认为GET
options.dataType=options.dataType || "json"; //响应数据格式,默认json

var params=formatParams(options.data);//options.data请求的数据

var xhr;
//考虑兼容性
if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}else if(window.ActiveObject){//兼容IE6以下版本
xhr=new ActiveXobject('Microsoft.XMLHTTP');
}

//启动并发送一个请求
if(options.type=="GET"){
xhr.open("GET",options.url+"?"+params,true);
xhr.send(null);
}else if(options.type=="POST"){
xhr.open("post",options.url,true);

//设置表单提交时的内容类型
//Content-type数据请求的格式
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(params);
}

// 设置有效时间
setTimeout(function(){
if(xhr.readySate!=4){
xhr.abort();
}
},options.timeout)

// 接收
// options.success成功之后的回调函数 options.error失败后的回调函数 //xhr.responseText,xhr.responseXML 获得字符串形式的响应数据或者XML形式的响应数据
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
var status=xhr.status;
if(status>=200&& status<300 || status==304){
options.success&&options.success(xhr.responseText,xhr.responseXML);
}else{
options.error&&options.error(status);
}
}
}
}

//格式化请求参数
function formatParams(data){
var arr=[];
for(var name in data){
arr.push(encodeURIComponent(name)+"="+encodeURIComponent(data[name]));
}
arr.push(("v="+Math.random()).replace(".",""));
return arr.join("&");

}
//基本的使用实例
ajax({
url:"http://server-name/login",
type:'post',
data:{
username:'username',
password:'password'
},
dataType:'json',
timeout:10000,
contentType:"application/json",
success:function(data){
      。。。。。。//服务器返回响应,根据响应结果,分析是否登录成功
}, //异常处理
error:function(e){
console.log(e);
}
})
</script>

Promise的出现主要是解决地狱回调的问题,比如你需要结果需要请求很多个接口,这些接口的参数需要另外那个的接口返回的数据作为依赖,这样就需要我们一层嵌套一层,但是有了Promise 我们就无需嵌套

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
function ajax(optionsOverride){
//将传入的参数与默认的合并
var options = {}
for(var k in ajaxOptions){
options[k] = optionsOverride[k] || ajaxOptions[k]
}
options.async = options.async === false ? false : true
var xhr = options.xhr = options.xhr || new XMLHttpRequest()

return new Promise(function(resolve,reject){
xhr.open(options.method,options.url,options.async)
xhr.timeout = options.timeout

//设置请求头
for(var k in options.headers){
xhr.setRuquestHeader(k,options,headers[k])
}
//注册xhr对象事件
xhr.onprogress = options.onprogress
xhr.onload.onprogress = options.onploadprogress
xhr.responseType = options.dataType

xhr.onabort = function(){
reject(new Error({
errorType: 'abort_error',
xhr:xhr
}))
}

xhr.ontimeout = function(){
reject({
errorType: 'timeout_error',
xhr:xhr
})
}


xhr.onerror = function(){
reject({
errorType: 'onerror',
xhr:xhr
})
}

xhr.onloadend = function(){
if ((xhr.status >= 200 && xhr.status< 300) || xhr.status == 304) {
resolve(xhr)
}else{
reject({
errorType: 'status_error',
xhr:xhr
})
}
try {
xhr.send(options.data)
} catch (e) {
reject({
errorType: 'send_error',
error:e
})
}
}

})
}

参考文章:

https://www.cnblogs.com/elexmiumiu/p/12196122.html

https://www.cnblogs.com/qing-5/p/11368009.html

-------------本文结束感谢您的阅读-------------