基于rcp的网络请求能力
rcp模块提供HTTP数据请求功能,请求性能如接口的易用性、性能、功耗方面,对比Network Kit HTTP网络API,rcp采用面向对象和场景的设计,API使用更简单、更灵活,满足不同场景的使用需求,具备更好的扩展性和更优的性能。支持如场景化网络API、网络代理、自定义DNS解析、自定义证书校验、服务器身份校验等特性。
场景描述
RCP网络库提供数据请求功能 涉及到的使用场景可参考如下:
场景一:调用rcp库实现基础的网络请求能力。
场景二:对标http原生库能力 使用post、get请求将多个文件采用表单形式上传至服务端做处理。
场景三:当根证书校验失败,请求使用自签名证书不支持/无法通过校验 或 证书过期需要重新修改证书时,通过rcp网络请求能力忽略证书校验。
场景四:为验证服务端和客户端之间的身份和数据完整性,确保通信的安全性。
场景五:不同的系统、不同的框架使用的域名解析机制不同,用户使用域名连接系统时,需要配置使用统一解析域名作为入口处理请求。
场景六: 请求时判断用户是否登录、判断用户是否有权限访问资源、处理cookie方式,调用rcp请求实现拦截器能力。
方案描述
场景一:
调用rcp库实现基础的网络请求能力。
效果图
方案
创建session会话后,调用模块支持的各类HTTP数据发送方式(FETCH、GET、POST、PUT等),有关能力可参考文档:rcp.session
核心代码
rcpTest(){
let testUrl = "https://www.xxx.com"
//定义通信会话对象
const sessionWithSecurityConfig = rcp.createSession();
//get请求
sessionWithSecurityConfig.get(testUrl).then((response) => {
console.log("test---------" + response.toString());
//页面展示请求结果
AlertDialog.show(
{
title: 'request接口回调结果',
message: '请求网站:' + testUrl + '\n\n' + 'Callback Data: ' + response.toString(),
})
}).catch((err:BusinessError)=> {
AlertDialog.show(
{
title: 'request接口回调结果',
message: '请求失败,错误信息:' + err.data,
})
console.error("test err:" + JSON.stringify(err));
});
}
场景二:
使用时希望通过post、get请求将多个文件采用表单形式携带上传至服务端做对应处理。
方案
请求地址采用post方式上传文件时需要携带多个文件,可通过MultipartForm多表单参数实现当前场景。
核心代码
let session = rcp.createSession();
let request = new rcp.Request('http://192.168.0.1:8080');
request.content = new rcp.MultipartForm({
file1: {
contentOrPath: {
content: new util.TextEncoder().encode('Text').buffer
}
},
file2: {
contentOrPath: {
content: new util.TextEncoder().encode('Text').buffer
}
},
});
try {
const resp = await session.fetch(request);
console.log("resp",JSON.stringify(resp))
expect(resp.statusCode).assertEqual(200);
} catch (e) {
expect(JSON.stringify(e)).assertEqual('99');
}
session.close();
场景三:
当根证书校验失败,请求使用自签名证书不支持/无法通过校验 或 证书过期需要重新修改证书时,希望通过rcp网络请求能力忽略证书校验。
效果图
方案
rcp网络库中可通过设置参数Configuration.security设置为 'skip' 以绕过证书校验,可参考文档:rcp.requestConfiguration
核心代码
let testUrl = "https://www.example.com"
//session中证书有关能力设置
const securityConfig: rcp.SecurityConfiguration = {
remoteValidation : 'skip'
};
//发起请求
const session = rcp.createSession({ requestConfiguration: { security: securityConfig } });
session.get(testUrl).then((response) => {
console.log('res timeInfo : ' + JSON.stringify(response));
}).catch((err: BusinessError) => {
console.error("err:" + JSON.stringify(err));
});
场景四:
为验证服务端和客户端之间的身份和数据完整性,确保通信的安全性,使用rcp库能力实现双向证书绑定能力。
效果图
方案
为实现双向证书绑定能力需要首先对服务端证书做校验,请求同时需要客户端证书做校验 可在Configuration接口包含配置参数rcp.Configuration
具体步骤可参考文档:RCP-双向证书校验能力
核心代码
//证书内容读取
getContext(this).area = 0
let context: Context = getContext(this);
const keyPemConent = context.resourceManager.getRawFileContentSync('baidu.pem')
//通信url地址
let kHttpServerAddress = "https://www.baidu.com";
try {
//建立通信请求
const session = rcp.createSession();
const request = new rcp.Request(kHttpServerAddress, "GET");
//设置请求参数
request.configuration = {
security: {
certificate: {
content: keyPemConent,
type: "PEM"
}
}
}
console.info("configuration:" + JSON.stringify(request.configuration));
//fetch方式获取请求结果
const response = await session.fetch(request);
console.info("证书校验成功", JSON.stringify(response));
let content1 = `${kHttpServerAddress} 证书校验成功` + JSON.stringify(response);
} catch (err) {
console.error("证书校验失败" + JSON.stringify(err));
let content1 = `${kHttpServerAddress} 证书校验失败` + JSON.stringify(err);
let e: BusinessError = err as BusinessError;
console.error("testTag Get push token catch error:" + JSON.stringify(e));
}
场景五:
不同的系统、不同的框架使用的域名解析机制不同,用户使用域名连接系统时,需要配置使用统一解析域名作为入口处理请求。
方案
如开发人员需要为HTTP请求配置域名系统(DNS),包括自定义DNS服务器或静态DNS规则,可在session对象中的DnsConfiguration参数处设置。
核心代码
// 1、自定义DNS服务器
const customDnsServers: rcp.DnsServers = [
{ ip: "8.8.8.8" },
{ ip: "8.8.4.4", port: 53 },
];
const sessionWithCustomDns = rcp.createSession({ requestConfiguration: { dns: { dnsRules: customDnsServers } } });
// 2、自定义静态DNS能力
const staticDnsRules: rcp.StaticDnsRules = [
{ host: "example.com", port: 80, ipAddresses: ["192.168.1.1", "192.168.1.2"] },
{ host: "sub.example.com", port: 443, ipAddresses: ["192.168.2.1"] },
];
const sessionWithStaticDns = rcp.createSession({ requestConfiguration: { dns: { dnsRules: staticDnsRules } } });
// 3、配置HTTP请求的DNS
const dohConfig: rcp.DnsOverHttpsConfiguration = {
url: "https://dns.example.com/dns-query",
skipCertificatesValidation: true,
};
const sessionWithDoh = rcp.createSession({ requestConfiguration: { dns: { dnsOverHttps: dohConfig } } });
场景六:
请求时判断用户是否登录、判断用户是否有权限访问资源、处理cookie方式,调用rcp请求实现拦截器能力。
方案
当前Api12配套版本上,rcp库中添加interceptors参数做对应的拦截器功能,有关参数说明可参考rcp.Interceptor
核心代码
//定义拦截器
class ResponseCache {
private readonly cache: any = {};
getResponse(url: string): rcp.Response {
return this.cache[url];
}
setResponse(url: string, response: rcp.Response): void {
this.cache[url] = response;
}
}
class ResponseCachingInterceptor implements rcp.Interceptor {
constructor(private readonly cache: ResponseCache) {}
async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
const url = context.request.url.href;
const responseFromCache = this.cache.getResponse(url);
if (responseFromCache) {
return Promise.resolve(responseFromCache);
}
const promise = next.handle(context);
promise.then((resp)=>{
resp.statusCode = 200;
cache.setResponse(url, resp);
});
return promise;
}
}
//使用rcp库拦截器能力
const cache = new ResponseCache();
async function testInterceptor() {
const session = rcp.createSession({
interceptors: [new ResponseCachingInterceptor(cache)]
});
const response1 = await session.get('https://www.example.com');
const response2 = await session.fetch(request);
}