基于rcp的网络请求能力

HarmonyOS官方账号
发布于 2024-10-10 08:54
浏览
0收藏

​rcp模块提供HTTP数据请求功能,请求性能如接口的易用性、性能、功耗方面,对比Network Kit HTTP网络API,rcp采用面向对象和场景的设计,API使用更简单、更灵活,满足不同场景的使用需求,具备更好的扩展性和更优的性能。支持如场景化网络API、网络代理、自定义DNS解析、自定义证书校验、服务器身份校验等特性。

场景描述

RCP网络库提供数据请求功能 涉及到的使用场景可参考如下:

场景一:调用rcp库实现基础的网络请求能力。

场景二:对标http原生库能力 使用post、get请求将多个文件采用表单形式上传至服务端做处理。

场景三:当根证书校验失败,请求使用自签名证书不支持/无法通过校验 或 证书过期需要重新修改证书时,通过rcp网络请求能力忽略证书校验。

场景四:为验证服务端和客户端之间的身份和数据完整性,确保通信的安全性。

场景五:不同的系统、不同的框架使用的域名解析机制不同,用户使用域名连接系统时,需要配置使用统一解析域名作为入口处理请求。

场景六: 请求时判断用户是否登录、判断用户是否有权限访问资源、处理cookie方式,调用rcp请求实现拦截器能力。

方案描述

场景一:

调用rcp库实现基础的网络请求能力。

效果图

基于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的网络请求能力-鸿蒙开发者社区

方案

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库能力实现双向证书绑定能力。

效果图

基于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); 
}


分类
收藏
回复
举报
回复
    相关推荐