当前位置:   article > 正文

Ts手动封装http请求_ts http 请求

ts http 请求

博主在进行Cocos小游戏的开始时,想要实现http请求。简单的用node.js在本地搭了一个服务器后,查询Cocos的官方文档以及网上搜索,都没有发现官方封装的API。

博主之前从事原生微信小程序开发以及uniapp开发,使用惯了方便快捷的requestAPI,以为这个是很简单的一个东西。结果Cocos官方并没有封装过http请求!也是走了很多弯路,手动封装了一下http请求(每次都使用原生Js写法真的很让人抓狂),这里写出代码和具体思路,供诸位参考。

一、Js原生http请求的实现介绍

首先,Js原生http请求是使用XMLHttpRequest实现的。虽然这个东东以XML为前缀,但是其实也可以进行JSON格式数据的传输。

  1. const xhr = new XMLHttpRequest();//创建XMLHttpRequest示例对象
  2. xhr.setRequestHeader('Content-Type','application/json');//设置请求头,用来适配json格式数据传输
  3. xhr.open('POST',url,true);//初始化请求,设置请求方式,请求地址,是否异步调用
  4. xhr.send(JSON.stringfy(params));//发送请求参数(请求参数是跟在url后面的一串字符串,如?name=张三&age=18)

值得注意的是,参数其实是不支持中文字符的,但是为什么我们传入name=张三也是合法的呢?原因是绝大多数浏览器会自动将中文字符进行转码,弄成%开头的一堆数字。原本我们也是需要在脚本里面使用encodeURI这个函数进行转码的,但是这活被浏览器干了,倒也省心。

这四行代码就可以实现简单的请求了。但是我们还没有拿到请求数据。

xhr内置四个监听函数

  1. xhr.onerror = ()=>{//处理错误逻辑}
  2. xhr.onprogress = ()=>{//处理加载逻辑}
  3. xhr.onloadend = ()=>{//处理请求结束逻辑}
  4. xhr.ontimeout = ()=>{//处理超时逻辑}

除此之外,还有一个可以监听到所有事件的函数

xhr.onreadystatechange = ()=>{//在这里处理所有事件逻辑}

一般来说,我们使用xhr.onreadystatechange就够了。

  1. xhr.onreadystatechange = ()=>{
  2. if(xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)){
  3. console.log(xhr.responseText)
  4. }
  5. }

readyState有几个可取值,分别代表不同状态,4就是加载完成的状态。status是请求的状态码,通常200为请求成功。之后在responseText中获得返回的数据,如果是JSON格式数据,还可以再调用JSON.parse来转成js对象。

二、封装请求实现思路

首先我们应该清楚为什么要实现封装。因为现有的请求太过于繁琐,需要在不同的地方设置很多参数。而事实上我们需要的是什么,我们只需要上传信息,然后拿到信息就可以了。而且,如果想要区别请求的状态,就需要利用到xhr的四个监听函数用来细分。与此同时,我们还需要建立错误反馈机制,用来方便之后调试。所以我们的思路是,进一步的封装应该要在利用xhr的多个监听函数的基础上,并且能够实现一次传参直接获得消息。

这方面也不能忽略的是,网络请求是需要较长的响应时间的。如果在网络条件比较差或者传输数据量比较大的情况下,使用同步请求会阻塞主线程,导致之后的程序无法运行。所以应该设计成异步函数。

  1. export class Http {
  2. public static get(url, callback, thisObj) {
  3. var xhr = new XMLHttpRequest();
  4. xhr.onerror = function () {
  5. callback.call(thisObj, "ERROR", xhr)
  6. }
  7. xhr.onprogress = function () {
  8. callback.call(thisObj, "PROGRESS", xhr)
  9. }
  10. xhr.onloadend = function () {
  11. callback.call(thisObj, "COMPLETE", xhr)
  12. }
  13. xhr.ontimeout = function () {
  14. callback.call(thisObj, "TIMEOUT", xhr)
  15. }
  16. xhr.open("GET", url, true);//这里的true意思是允许异步请求
  17. xhr.setRequestHeader('Content-Type', 'application/json');
  18. xhr.send();//这里不写参数的原因是,参数也可以直接放在url里,我们在进一步封装之后,直接写到url中
  19. }
  20. }

首先进行简单封装,设置请求方式和数据格式。这个模块只能实现最简单的请求功能。

  1. httpSend(subUrl, params, callback) {
  2. var param = this.obj_contact(params);
  3. var url = this.baseUrl + '/' + subUrl + param;
  4. Http.get(url, function (eventName: string, xhr: XMLHttpRequest) {
  5. if (eventName == 'COMPLETE') {
  6. if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
  7. var response = JSON.parse(xhr.responseText)
  8. callback && callback(response);
  9. } else {
  10. console.log('服务器维护中');
  11. }
  12. } else if (eventName == 'TIMEOUT') {
  13. console.log("连接网关超时")
  14. } else if (eventName == 'ERROR') {
  15. console.log("连接网关发生错误")
  16. }
  17. }, this);
  18. }

接着进行第二步封装,这步封装中我们利用了回调函数。第一步封装我们传入回调函数两个参数,分别为请求状态字符串和xhr实例对象。返回的数据储存在xhr实例对象内,所以必须传入,而请求状态字符串可以提示当前的请求状态,也需要传入。这里说明一下baseUrl就是所请求网站的域名,subUrl就是该网站域名下的文件路径。然后通过自己写的一个函数obj_contact来将js对象转化为?key1=value1&key2=value2...的格式,加到完整域名的后面。

这里写出obj_contact的具体实现

  1. public obj_contact(obj) {
  2. var s = "";
  3. for (var k in obj) {
  4. let v = obj[k];
  5. if (s.length == 0) {
  6. s += "?" + k + "=" + v;
  7. } else {
  8. s += "&" + k + "=" + v;
  9. }
  10. }
  11. return s;
  12. }

一个很简单的函数。

写到这里,我们发现还没有拿到服务器返回的消息。其实可以两步解决的,在第一步封装的回调函数里我们就可以把xhr.responseText当做参数返回的。但是我们的函数体会显得很臃肿,因为第二步封装里的函数还需要执行请求状态的判断,所以我们进行第三步封装。

  1. var params = {"name":"张三","id":"01","age":"18"};
  2. var subUrl = "test/demo";
  3. httpGet(subUrl, params, (res) => {
  4. if (res.code == 200) {
  5. if (res.data) {
  6. this.data = res.data
  7. }
  8. })

现在我们的函数看上去就很简洁了,只需要传入两个信息就能得到数据了,同样,Post请求也可以这样封装。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/285737
推荐阅读
相关标签
  

闽ICP备14008679号