本文讲的是封装下ArkTs的HTTP请求,做一下公共的拦截,并使用这个lib发起一次请求。
出来混的,封装一个lib已经是一个必备的技能了,尤其是做前端开发的,哪个HTTP请求不需要做统一的拦截处理呢,所以,今天除了介绍下ArkTs中的HTTP请求之外,还会说一下如何封装一个HTTP请求,以便做统一拦截
贪多嚼不烂,第一步我们需要先了解下ArkTs中的HTTP请求是怎么样的,又有哪一些步骤,而不是直接一上来就丢出一个例子,跟人说你已经封装好了,不然人家一问三不知。
需要下面的权限,文件的路径贴在了下面,申请权限这一块按下不表,因为不是重点。
src/main/module.json5
requestPermissions:[
{
"name" : "ohos.permission.INTERNET"
}
]
接下来,就按照官网上的request接口开发步骤,使用http请求。
import http from ‘@ohos.net.http’;
第一步的引入,我们并不需要手动去写那么一行代码,当我们第二步创建一个http实例的时候,开发工具会自动帮我们引入这个包,结合上一篇博客,我们需要在页面的aboutToAppear方法中创建,代码如下:
import http from '@ohos.net.http';
@Entry
@Component
export struct Found {
aboutToAppear() {
const httpRequest = http.createHttp();
console.log("当前调用了aboutToAppear方法");
}
build() {
}
}
由于获取订阅http响应头事件在前端的用处不大,所以暂时跳过,文章的后面将其与取消订阅http响应头事件一起说。
创建好了示例,自然是要设置请求参数了,为了方便,这儿直接设置Url为百度,且设置请求的方式为Get请求。则代码编写如下:
aboutToAppear() {
const httpRequest = http.createHttp();
httpRequest.request(
"https://www.baidu.com",
{
// 设置为get请求
method:http.RequestMethod.GET,
}
)
}
当前由于只有一个最简单的get请求,所以只需要传入地址以及请求方式,而其他的参数的描述,按照官网,粘贴如下:
其中最重要的,自然就是我们的header以及extraData。
至此,一个请求是发出去了,接下来就是获取消息了,但是官网上的方式是如下
httpRequest.request(url,params,callback)
站在前端开发的基础上,我们自然可以使用Async-Await优化了,所以代码如下:
async aboutToAppear() {
const httpRequest = http.createHttp();
const data = await httpRequest.request(
"https://www.baidu.com/s?ie=UTF-8&wd=ArkTs%E5%B0%81%E8%A3%85%E7%BD%91%E7%BB%9C%E8%AF%B7%E6%B1%82%E5%B9%B6%E5%8F%91%E8%B5%B7%E4%B8%80%E4%B8%AAGet%E8%AF%B7%E6%B1%82",
{
// 设置为get请求
method: http.RequestMethod.GET,
}
)
console.log("data====================>");
console.log(JSON.stringify(data.result));
console.log(JSON.stringify(data.cookies))
console.log(JSON.stringify(data.responseCode))
}
为了方便以及验证官网上所说的,还有err以及resoponse是什么,我们将路径修改下
"https://www.abc123def456.com"
请耐心听我的废话,因为我们做拦截器的时候,对这些错误要有了解.
而我们既然用了Async-Await,那么错误拦截就必须要放在catch中,所以我们可以这么处理。
const data:any = await httpRequest.request(
// "https://www.aidu.com/s?ie=UTF-8&wd=ArkTs%E5%B0%81%E8%A3%85%E7%BD%91%E7%BB%9C%E8%AF%B7%E6%B1%82%E5%B9%B6%E5%8F%91%E8%B5%B7%E4%B8%80%E4%B8%AAGet%E8%AF%B7%E6%B1%82",
"https://www.abc123def456.com",
{
// 设置为get请求
method: http.RequestMethod.GET
}
).catch((err:any)=>{
console.log("出现错误了!!!!!");
console.log(JSON.stringify((err)));
Promise.reject(err);
})
返回的结构如下:
也就是说我们的错误原因是地址写错了,所以无法找到这个服务器。
即然如此,我们就可以封装下,将返回的错误统一成500,不建议根据每个code去查询是什么bug,建议直接设置一个状态码以及打印出日志。
按照这个思路,我们的代码如下:
const data:any = await httpRequest.request(
"https://www.abc123def456.com",
{
// 设置为get请求
method: http.RequestMethod.GET
}
).catch((err:any)=>{
console.log("出现错误了!!!!!");
return ({"responseCode":500,result:err.message});
})
console.log("data====================>");
console.log(JSON.stringify(data?.result));
console.log(JSON.stringify(data?.cookies))
console.log(JSON.stringify(data?.responseCode))
}
需要注意的是,第九行中我直接将结构体returen出去,这样子我们才能在下面拦截到数据。
具体需要怎么操作,哪些字段,建议看自己的项目来设置返回体。
关闭http请求
第六步依旧涉及到“订阅http响应头事件”,按下不表,继续看第七步的httpRequest.destroy();
由于我们已经用了Async-Await了,所以我们就直接在最后加上这一个就可以了,不需要说再在error的时候分别添加
一般来说,开发都不怎么需要关闭http请求,因为接受完数据后,我们的http通道都会自动关闭,但是鸿蒙要求我们手动关闭,所以我们最好听人劝,吃饱饭。
async aboutToAppear() {
const httpRequest = http.createHttp();
const data:any = await httpRequest.request(
"https://www.abc123def456.com",
{
// 设置为get请求
method: http.RequestMethod.GET
}
).catch((err:any)=>{
console.log("出现错误了!!!!!");
return ({"responseCode":500,result:err.message});
})
//关闭请求
httpRequest.destroy();
console.log("data====================>");
console.log(JSON.stringify(data?.result));
}
Response Header 顾名思义,就是请求返回的header接收到的时候,可以直接在这处理,但是我们一般用的比较少,因为相比之下,我们更需要的是body的内容。
在返回头中,最主要是做空值判断,比如当页面返回的是null,也就是请求头中会设置字节数为0,这个时候就可以跳过对我们请求的处理了
虽然用的不多,但是照例写一下。
httpRequest.on('headersReceive', (header) => {
console.info('这个是headersReceive事件');
});
但是很可惜…
在请求失败的情况下,没有header返回,这也是我比较少用的原因…
封装
即然现在对于HTTP请求已经熟悉了,我们就可以封装了,而刚其实也封装的差不多了,只是我们可以再加一个Promise.
代码如下:
async getHttp(url: string, method: http.RequestMethod, body?: any) {
return new Promise(async (resolve, reject)=>{
const httpRequest = http.createHttp();
const data: any = await httpRequest.request(
url,
{
// 设置为get请求
method,
extraData:body?body:undefined
}
).catch((err: any) => {
console.log("出现错误了!!!!!");
return ({ "responseCode": 500, result: err.message });
})
//关闭请求
httpRequest.destroy();
console.log("data====================>");
console.log(JSON.stringify(data?.result));
resolve(data);
}
)
}
其中,有几个点是需要讲一下
定义到使用的过程,是定义一次,完成一次之后就销毁的
代码中的body,如果没有传的时候,是传过去undefined,自动会被忽略掉,同理,header也可以设置一个默认的。或者是直接修改request的第二个参数.
因为async/await返回的是promise。所以有可能会导致页面卡断,但是这个可以忽略不计!
接下来,写一个For循环请求测试下。
async aboutToAppear() {
let num = [1, 2, 3, 4, 5];
for (let i in num) {
const data = await this.getHttp(
"https://www.baidu.com",
http.RequestMethod.GET);
}
}
使用for循环的原因是因为可以跟Async-Await 搭配使用,效果如下:
可以看到,好一个整齐划一的日志!!
封装结束。其实有javasxcipe开发经验的都可以知道我的思路,基本就是封装Axios那一套,所以大家不用太紧张,Async-Await用的好就可以了。
最后,一般我们会将其封装成一个为文件,这个看人而已。
主要介绍前端开发的博客,由衷期望各位大佬们扫码关注