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

HarmonyOS码上奇行
7k 声望2.8k 粉丝