HarmonyOS中的http请求及其封装(附案例)

打印 上一主题 下一主题

主题 831|帖子 831|积分 2493

概述

HarmonyOS提供了@ohos.net.http模块,它提供了Http数据请求能力。当在应用开辟中必要使用http获取服务端数据时可以导入该模块实现http请求的发送。
@ohos.net.http模块提供http数据请求能力。应用可以通过http发起一个数据请求,支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。
怎样使用?

要想使用http请求,体系必须要具备ohos.permission.INTERNET权限,在model.json5文件中的module模块下添加如下请求权限:
  1. "requestPermissions": [
  2.   {
  3.     "name": "ohos.permission.INTERNET"
  4.   }
  5. ],
复制代码
完整示例

该例引用自鸿蒙开辟文档@ohos.net.http (数据请求)
  1. // 引入包名
  2. import http from '@ohos.net.http';
  3. // 每一个httpRequest对应一个HTTP请求任务,不可复用
  4. let httpRequest = http.createHttp();
  5. // 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
  6. // 从API 8开始,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)。 8+
  7. httpRequest.on('headersReceive', (header) => {
  8.     console.info('header: ' + JSON.stringify(header));
  9. });
  10. httpRequest.request(
  11.     // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
  12.     "EXAMPLE_URL",
  13.     {
  14.         method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
  15.         // 开发者根据自身业务需要添加header字段
  16.         header: {
  17.             'Content-Type': 'application/json'
  18.         },
  19.         // 当使用POST请求时此字段用于传递内容
  20.         extraData: {
  21.             "data": "data to send",
  22.         },
  23.         expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
  24.         usingCache: true, // 可选,默认为true
  25.         priority: 1, // 可选,默认为1
  26.         connectTimeout: 60000, // 可选,默认为60000ms
  27.         readTimeout: 60000, // 可选,默认为60000ms
  28.         usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
  29.     }, (err, data) => {
  30.         if (!err) {
  31.             // data.result为HTTP响应内容,可根据业务需要进行解析
  32.             console.info('Result:' + JSON.stringify(data.result));
  33.             console.info('code:' + JSON.stringify(data.responseCode));
  34.             // data.header为HTTP响应头,可根据业务需要进行解析
  35.             console.info('header:' + JSON.stringify(data.header));
  36.             console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
  37.             // 取消订阅HTTP响应头事件
  38.             httpRequest.off('headersReceive');
  39.             // 当该请求使用完毕时,调用destroy方法主动销毁
  40.             httpRequest.destroy();
  41.         } else {
  42.             console.info('error:' + JSON.stringify(err));
  43.             // 取消订阅HTTP响应头事件
  44.             httpRequest.off('headersReceive');
  45.             // 当该请求使用完毕时,调用destroy方法主动销毁。
  46.             httpRequest.destroy();
  47.         }
  48.     }
  49. );
复制代码
http.createHttp

这是源码中对createHttp的方法的封装,它的返回值是一个HttpRequest对象。
  
  1. /**
  2. * Creates an HTTP request task.
  3.  * 创建一个HTTP请求任务,返回值为HttpRequest对象
  4. */
  5. function createHttp(): HttpRequest;
复制代码
HttpRequest接口文件中封装了request、destory、on、off、once方法,见以下源码注释:
详细解析参考HarmonyOS开辟文档
  
  1. export interface HttpRequest {
  2.     /**
  3.      * Initiates an HTTP request to a given URL.
  4.      * 向给定的URL地址发送一个HTTP请求
  5.      */
  6.     request(url: string, callback: AsyncCallback<HttpResponse>): void;
  7.     request(url: string, options: HttpRequestOptions, callback: AsyncCallback<HttpResponse>): void;
  8.     request(url: string, options?: HttpRequestOptions): Promise<HttpResponse>;
  9.     /**
  10.      * Destroys an HTTP request.
  11.      * 销毁一个HTTP请求
  12.      */
  13.     destroy(): void;
  14.     /**
  15.      * Registers an observer for HTTP Response Header events.
  16.      * 订阅HTTP响应头事件
  17.      * @deprecated since 8
  18.      * @useinstead on_headersReceive
  19.      */
  20.     on(type: "headerReceive", callback: AsyncCallback<Object>): void;
  21.     /**
  22.      * Unregisters the observer for HTTP Response Header events.
  23.      * 取消订阅HTTP响应头事件
  24.      * @deprecated since 8
  25.      * @useinstead off_headersReceive
  26.      */
  27.     off(type: "headerReceive", callback?: AsyncCallback<Object>): void;
  28.     /**
  29.      * Registers an observer for HTTP Response Header events.
  30.      * 订阅HTTP响应头事件
  31.      * @since 8
  32.      */
  33.     on(type: "headersReceive", callback: Callback<Object>): void;
  34.     /**
  35.      * Unregisters the observer for HTTP Response Header events.
  36.      * 取消订阅HTTP响应头事件
  37.      * @since 8
  38.      */
  39.     off(type: "headersReceive", callback?: Callback<Object>): void;
  40.     /**
  41.      * Registers a one-time observer for HTTP Response Header events.
  42.      * 订阅一次HTTP响应头事件
  43.      * @since 8
  44.      */
  45.     once(type: "headersReceive", callback: Callback<Object>): void;
  46. }
复制代码
 HttpRequestOptions

发送http请求携带的参数。
参数详情及取值范围
名称类型必选项阐明
methodRequestMethod(罗列) 请求方式
extraDatastring | Object | ArrayBuffer(API8以后)发送请求的额外数据,用于http请求的POST、PUT方法
expectDataTypeHttpDataType(罗列)指定返回数据的类型,假如指定了,将优先返回指定的类型
useingCache(API9之后)boolean是否使用缓存,默认为true
priority(API9后)number优先级,取值为[1,1000],默认为1
headerObjecthttp请求头字段,默认为{‘Content-Type’:'application/json'}
redTimeoutnumber读取超时时间,单位ms,设置为0时表示不会出现超时情况
connectTimeoutnumber连接超时时间,单位ms
usingProtocol(API9之后)HttpProtocol(罗列)使用的http协议,默认值由体系指定
RequestMethod

  
  1. export enum RequestMethod {
  2.     OPTIONS = "OPTIONS",
  3.     GET = "GET",
  4.     HEAD = "HEAD",
  5.     POST = "POST",
  6.     PUT = "PUT",
  7.     DELETE = "DELETE",
  8.     TRACE = "TRACE",
  9.     CONNECT = "CONNECT"
  10. }
复制代码
 HttpDataType

  
  1. /**
  2. * Indicates the type of the returned data.
  3. * 指定返回数据的类型
  4. * @since 9
  5. */
  6. export enum HttpDataType {
  7.     STRING,
  8.     OBJECT = 1,
  9.     ARRAY_BUFFER = 2
  10. }
复制代码
HttpProtocol

  
  1. /**
  2. * Supported protocols.
  3. * 支持的协议
  4. * @since 9
  5. */
  6. export enum HttpProtocol {
  7.     HTTP1_1,
  8.     HTTP2
  9. }
复制代码
HttpResponse 

request方法回调函数的返回值类型。
名称类型阐明
resultstring | Object | ArrayBuffer(API6之后)HTTP请求根据响应头中Content-type类型返回对应的响应格式内容
resultType(API 9之后)HttpDataType(罗列)返回值类型
responseCodeResponseCode | number回调函数执行乐成时,此字段为ResponseCode。若执行失败,错误码会从AsyncCallback中的err字段返回
headerObjecthttp请求返回的响应头
 封装http请求及案例

封装Response

按照后端返回的数据格式封装Response
  1. export default class Response{
  2.   /**
  3.    * 响应码
  4.    */
  5.   code: number
  6.   /**
  7.    * 相应消息
  8.    */
  9.   msg: string
  10.   /**
  11.    * 相应数据
  12.    */
  13.   data: any
  14. }
复制代码
封装http请求

封装http请求方法,并且处理返回值。将http请求函数作为可导出模块,之后在其他模块中引用即可使用http请求,同Axios。
注意:假如使用当地模拟器,使用"http://locaohost:端标语"不能完成请求,必要将localhost更换为本机的ip地址
http请求封装引自鸿蒙 HarmonyOS4.0 Http数据请求封装详解-CSDN博客
https://blog.csdn.net/qq_68512683/article/details/134724984
  1. import http from '@ohos.net.http';
  2. import Response from './Response';
  3. //导出httpRequest请求函数
  4. export function request(url: string, method: http.RequestMethod, requestData?: any): Promise<Response>{
  5.   //如果使用本地模拟器,则ip为本机的IP地址
  6.   const BASE_URL: string = "http://ip:服务端端口号"
  7.   let httpRequest = http.createHttp()
  8.   let responseResult = httpRequest.request(
  9.     BASE_URL + url,
  10.     {
  11.       method: method,
  12.       header: {
  13.         'Content-Type': 'application/json'
  14.       },
  15.       //携带额外参数
  16.       extraData: JSON.stringify(requestData),
  17.       //可选,默认为60000ms
  18.       connectTimeout: 60000,
  19.       readTimeout: 60000,
  20.     }
  21.   )
  22.   let response = new Response();
  23.   //处理数据,并返回
  24.   return responseResult.then((value: http.HttpResponse) => {
  25.     if (value.responseCode === 200) {
  26.       //获取返回数据,将返回的json数据解析成事先预定好的响应格式
  27.       //这里建议和后端的保持一致
  28.       let res: Response = JSON.parse(`${value.result}`);
  29.       response.data = res.data;
  30.       response.code = res.code;
  31.       response.msg = res.msg;
  32.      }else {
  33.        response.msg = '请求错误';
  34.        response.code = 400;
  35.      }
  36.      return response;
  37.   }).catch(() => {
  38.     response.msg = '请求错误';
  39.     response.code = 400;
  40.     return response;
  41.   });
  42. }
复制代码
案例

后端接口请自行设计。
登录页面
  1. import router from '@ohos.router'
  2. import { User } from '../entity/User'
  3. import { login } from './httpRequest/UserRelated'
  4. /**
  5. * 登录页面
  6. */
  7. @Entry
  8. @Component
  9. struct Login{
  10.   @State user: User = new User('','')
  11.   build(){
  12.     Column({space: 10}){
  13.       Row(){
  14.         Text('+86')
  15.         TextInput({placeholder: '请输入手机号'})
  16.           .type(InputType.PhoneNumber)
  17.           .height(45)
  18.           .backgroundColor('#ffffff')
  19.           .padding(10)
  20.           .layoutWeight(1)
  21.           .onChange(value =>{
  22.             this.user.phone = value
  23.           })
  24.       }.padding({left: 20, right: 20})
  25.       Row(){
  26.         TextInput({placeholder: '请输入密码'})
  27.           .type(InputType.Number)
  28.           .height(45)
  29.           .backgroundColor('#ffffff')
  30.           .padding({left: 0, right: 0})
  31.           .layoutWeight(1)
  32.           .onChange(value =>{
  33.             this.user.password = value
  34.           })
  35.       }.padding({left: 20, right: 20})
  36.       Row(){
  37.         Button('登 录')
  38.           .type(ButtonType.Normal)
  39.           .fontSize(20)
  40.           .width('100%')
  41.           .borderRadius(20)
  42.           .backgroundColor('#2f90b9')
  43.           .fontColor('#ffffff')
  44.           .onClick(() => {
  45.             login(this.user).then(res =>{
  46.               if (res.code === 1) {
  47.                 router.pushUrl({
  48.                   url: 'pages/Index'
  49.                 })
  50.               } else {
  51.                 AlertDialog.show({
  52.                   title: '警告',
  53.                   message: res.msg
  54.                 })
  55.               }
  56.             })
  57.           })
  58.       }.padding({left: 20, right: 20})
  59.     }
  60.     .width('100%')
  61.     .height('100%')
  62.     .justifyContent(FlexAlign.Center)
  63.   }
  64. }
复制代码
用户相干http请求
将http请求从页面中抽离出来封装在一个ets文件中,在页面中直接引用方法即可。不混杂在页面代码中,加强代码可读性。
  1. import http from '@ohos.net.http'
  2. import { User } from '../../entity/User'
  3. import { request } from '../../utils/httpUtils/Request'
  4. /**
  5. * 用户相关数据请求
  6. * @returns
  7. */
  8. export function login(user: User){
  9.   return request('/user/user/login', http.RequestMethod.POST, user)
  10. }
复制代码
用户对象
不在页面中定义,页面只进行数据项的定义和数据渲染即可,加强代码可读性。
  1. export class User{
  2.   phone: String
  3.   password: String
  4.   constructor(phone: String, password: String) {
  5.     this.phone = phone
  6.     this.password = password
  7.   }
  8. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

石小疯

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表