编程日志(01)--cocosCreator实现类似jQuery的ajax

为什么在cocosCreator中不使用axios等工具

cocosCreator版本:2.0.7

在游戏场景中少不了要使用网络交互,在以往的编程中,用jQuery实现或者axios实现并不是很难,从论坛的反馈来看,cocos对ES6的支持尤其是promise,经过长时间的更新似乎依然没有很好地完善,由于开发时间限制,这里就没有去体验这些说法直接使用回调函数避免兼容性问题原始实现ajax请求。

构造ajax方法

使用XMLHttpRequest实现ajax请求并不困难,这里需要注意的是针对IE10以下版本ActiveXObject的兼容性问题,目前个人没有去验证这一点,且项目本生要求支持基于vue的webview。下面是官方文档给的一个示例

1
2
3
4
5
6
7
8
9
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
var response = xhr.responseText;
console.log(response);
}
};
xhr.open("GET", url, true);
xhr.send();

我的目的是实现像JQuery一样使用$.ajax(),只需要定义好传参结构就可以了,且由于目前是自己使用,可以只给出核心功能,参数的检验可以之后完善。下面是完整代码,定义cc.global方便全局使用。

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

cc.global = {
ajax: function(obj) {

let err = '';
var xhr = cc.loader.getXMLHttpRequest();
xhr.open(obj.type, obj.url);
if (obj.type.toUpperCase() == 'GET') {
xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");

} else if (obj.type.toUpperCase() == 'POST') {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
}
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status <= 207)) {
err = false;
} else {
err = true;
}
if (err) {
//错误处理
if (obj.error) {
obj.error()
}
} else {
if (obj.success) {
obj.success(JSON.parse(xhr.responseText))
}
}
};

xhr.send(obj.data ? cc.global.qsPrimitive(obj.data) : null);
}
}
1
2
3
4
5
6
7
8
9
10
11
cc.global.ajax({
type: 'post',
url: '',
data: {
userCode:'ac',
userPwd:'pwd'
},
success: function(res) {
console.log(res)
}
})

非常简单,但是还有问题需要说明一下

qs的实现

根据post请求协议规定,post数据需要放在Request body中传输,四种常见的 POST 提交数据方式(application/x-www-form-urlencoded,multipart/form-data,application/json,text/xml),这些可以再研究一下。

在项目中主要用到的还是get请求和post的请求,他们直观的区别就在于GET参数是放在Query Params上,通过在地址后面拼接如下qs序列化的参数来传参,而POST不是说不可以将参数拼在地址里,关于这一点可以参考99%的人都理解错了HTTP中GET与POST的区别,只是有参数的长度限制以及规范使用。目前的项目中需要传递比较大的数据,因此需要将其放在在Request body中

1
?key1=value1&key2=value2

(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url

不管是GET还是POST的x-www-form-urlencoded方式,都要求将参数qs序列化。

下面是从node querrystring模块源码扒出的简化的方法,核心只是一个循环语句只需注意一下中文编码的问题

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
// 简单查询序列化
qsPrimitive: function(obj) {
var sep = sep || '&';
var eq = eq || '=';

// 假设value都是字符串
if (obj !== null && typeof obj === 'object') {
var keys = Object.keys(obj);
var len = keys.length;
var flast = len - 1;
var fields = '';
for (var i = 0; i < len; ++i) {
var k = keys[i];
var v = obj[k];
var ks = encodeURIComponent(k) + eq;
fields += ks + encodeURIComponent(v);
if (i < flast)
fields += sep;

}
return fields;
} else {
return '';

}

},

Author: sumshare
Link: http://blog.sumshare.cn/2019/05/27/cocosCreatorAjax/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.