写点什么

鸿蒙应用开发从入门到入行 - 篇 7:http 网络请求

作者:猫林老师
  • 2024-12-18
    广东
  • 本文字数:5443 字

    阅读完需:约 18 分钟

鸿蒙应用开发从入门到入行 - 篇7:http网络请求

鸿蒙应用开发从入门到入行

第七天 - http 网络请求

导读:在本篇文章里,您将掌握鸿蒙开发工具 DevEco 的基本使用、ArkUI 里的基础组件,并通过制作一个简单界面掌握使用

HarmonyOS - 网络请求概述

  • 在应用开发中,少不了需要向云端发送请求进行交互,这就需要进行网络通信。在 HarmonyOS 中,把所有跟请求有关的能力全部放入了NetworkKit(系统内置网络服务工具包)里,因此用之前需要先导入

  • 目前 HarmonyOS 支持如下几种方式网络请求

  • http

  • 通过 HTTP 发起一个数据请求。

  • WebSocket

  • 使用 WebSocket 建立服务器与客户端的双向连接。

  • Socket

  • 通过 Socket 进行数据传输。

  • 网络连接管理

  • 网络连接管理提供管理网络一些基础能力,包括 WiFi/蜂窝/Ethernet 等多网络连接优先级管理、网络质量评估、订阅默认/指定网络连接状态变化、查询网络连接信息、DNS 解析等功能。

  • MDNS

  • MDNS 即多播 DNS(Multicast DNS),提供局域网内的本地服务添加、移除、发现、解析等能力。

  • 本篇主要讲述 http,因为咱们开发用的最多的就是它了

http 请求 - 权限申请

  • 注意:如果要使用网络请求,必须申请权限

  • 哪个模块需要用,就在哪个模块的module.json5文件里进行申请

  • 如果初学者目前的项目仅有一个模块,也即创建项目自动生成的entry模块

  • 具体路径为:entry -> src -> main -> module.json5

  • 找到配置文件后,找到requestPermissions这一项

  • 若没有则创建,创建方法为,在此配置文件任意根节点处输入如下内容


        "requestPermissions": [                  ],
复制代码


  • 技巧:找个根节点输入 req,DevEco即可出提示,按回车即可


  • requestPermissions即配置你想申请的权限,格式如下


      "requestPermissions": [        {          "name": "权限名1",          "reason": "申请原因",          "usedScene": "使用场景        },        {          "name": "权限名2",          "reason": "申请原因",          "usedScene": "使用场景"        }      ],
复制代码


  • 其中name是必须填的且有固定格式,例如要申请网络权限则必须写:ohos.permission.INTERNET

  • reason 和 usedScene 是可选的(这两个一个上架审核要用,一个对权限做更细致场景划分,目前我们暂时不用)

  • 我们目前仅需申请网络请求权限,因此做如下配置(技巧:随便输入内容关键字,DevEco 都有提示,按回车即可)


   "requestPermissions": [        {          "name": "ohos.permission.INTERNET",        }      ]
复制代码


  • 注:

  • 在最新版本中:即使不申请权限也能在预览器上发请求但会有警告。但若要模拟器或真机能请求,还请配置权限!

http 请求 - 使用详解

基本使用

  • 使用步骤

  • 从 @kit.NetworkKit 中导入 http 命名空间。

  • 调用 createHttp()方法,创建一个 HttpRequest 对象。

  • 调用该对象的 request()方法,传入 http 请求的 url 地址和可选参数,发起网络请求。

  • 按照实际业务需要,解析返回结果。

  • 当该请求使用完毕时,调用 destroy()方法主动销毁。

  • 对应代码如下


  // 1. 引入包名  import { http } from '@kit.NetworkKit';    // 2. 调用createHttp()方法,创建一个HttpRequest对象。  let httpRequest = http.createHttp();    // 3. 调用该对象的request()方法,传入http请求的url地址和可选参数,发起网络请求。  // 总结:参数1为请求路径  参数2是一个对象,用来控制请求的相关配置, 参数3是请求完成的回调函数  httpRequest.request(    // 请求地址    "url",    {      method: http.RequestMethod.POST, // 请求方式,可选,默认为http.RequestMethod.GET      // 开发者根据自身业务需要添加header字段      header: [{        // 例如指定请求体类型        'Content-Type': 'application/json'      }],      // 请求携带的参数。一般情况下:post、put等请求传入对象,get请求传`key=value`形式字符串      extraData: "data to send",    }, (err: BusinessError, data: http.HttpResponse) => {      if (!err) {                // 4. 按照实际业务需要,解析返回结果。        //     data.result为HTTP响应内容,可根据业务需要进行解析        console.info('Result:' + JSON.stringify(data.result));        console.info('code:' + JSON.stringify(data.responseCode));        // 5. 当该请求使用完毕时,调用destroy方法主动销毁        httpRequest.destroy();              } else {                console.error('error:' + JSON.stringify(err));        // 5. 当该请求使用完毕时,调用destroy方法主动销毁        httpRequest.destroy();      }    }  );
复制代码


  • 上面代码的注释请大家一定要看,因为涵盖了知识点解析

  • 当然,光看代码不如实操。我们通过请求一个 get,请求一个 post 来试试

  • get 请求接口:

  • 一个获取多条随机笑话的接口

  • url:http://ajax.zll.cool/joke/list

  • 请求参数类型:urlencoded

  • 参数:

  • num:数字,传几代表获取几条笑话

  • 响应体:

  • 返回一个字符串数组

  • 请求代码如下


    Button('发get请求')            .onClick(() => {              // 创建请求对象              const httpRequest = http.createHttp()              httpRequest.request('http://ajax.zll.cool/joke/list', {                // 参数                extraData: 'num=3'              },               // 请求完成(不管成功还是失败)都调用的回调函数              (err: BusinessError, data: http.HttpResponse) => {                 if (!err) {                  // 如果err无值代表请求成功,打印响应体                  console.info('Result:' + JSON.stringify(data.result));                  // 销毁请求对象                  httpRequest.destroy()                }              })            })
复制代码


  • 打印结果如下


  • 这里稍微说明一下:

  • 请求完成的回调函数里,data 即返回的响应内容,其中 data 里的result属性即为服务器返回的响应体。整个 data 属于HttpResponse类型,这种类型除了 result 以外,还有responseCode等属性,其他属性这里不做介绍,可自行翻阅官方文档

  • data.result 得到的是string | Object | ArrayBuffer联合类型中的一种,因此如果服务器返回的是 JSON 字符串那就是 string 类型(例如本接口返回的就是 JSON),想要使用,还得把 JSON 字符串转成 js 数据。使用JSON.parse做转换,上例没有给出。大家可自行测试,若要转换,加入以下代码


      JSON.parse(data.result.toString())
复制代码


- 注意:必须把`result`转成字符串,因为`ArkTS`是类型严谨的语言,`result`是联合类型,并不一定意味着只是字符串,所以如果不调用`toString`转字符串,上述代码会报错。当然你也可以用其他形式转成字符串,例如
复制代码


      JSON.parse(data.result + '')      JSON.parse(`${data.result}`)
复制代码


- **特别需要注意的是 JSON.parse 在API12中有新的实现,如果你敲JSON时出提示按回车有可能会导入新的实现。新实现里JSON.parse类型更严谨,还需要做断言才可使用。不想断言的同学,尽量手敲JSON**
- 最后,记得要销毁请求对象,即调用:`httpRequest.destroy()`。
- 原因:鸿蒙官方文档上明确写出http每个请求对象只能发一次请求。所以用完即销毁,免得占用资源。(经猫林老师在现版本测试,一个对象可以发多个请求。但是为避免将来有问题,请严格按官方文档推荐:**一个对象对应一个请求,用完即销毁**)
复制代码


  • 这里顺便给各位同学一个小作业:

  • 把本接口得到的笑话,渲染到界面

  • post 请求接口:

  • 一个注册用户的接口

  • url: http://ajax.zll.cool/user/reg

  • 请求参数类型:application/json

  • 参数:

  • username:用户名

  • 代码如下


              const httpRequest = http.createHttp()              httpRequest.request('http://ajax.zll.cool/user/reg', {                method: http.RequestMethod.POST,                header: [                  { 'Content-Type': 'application/json' }                ],                extraData: { username: 'jack' }              },                (err: BusinessError, data: http.HttpResponse) => {                  if (!err) {                    console.info(JSON.stringify(data.result))                  }                      httpRequest.destroy()                }              )
复制代码


  • 结果如下


Promise 用法

  • 上述使用是完全按官方指南所写。实际上自习翻阅官方 API 可发现 http 模块是支持 Promise 调用的。因此,上述发请求时的第三个参数(请求完成的回调)可以不写,而改成thencatch的方式,如


  // get请求            const httpRequest = http.createHttp()            httpRequest.request('http://ajax.zll.cool/joke/list', {              extraData: 'num=3'            })              .then((data: http.HttpResponse) => {                // 成功                console.info(JSON.stringify(data.result))              })              .catch((err: BusinessError) => {                // 失败                console.info(err.message)              })              .finally(() => {                // 不管成功失败都销毁请求对象                httpRequest.destroy()              })      // post请求            const httpRequest = http.createHttp()            httpRequest.request('http://ajax.zll.cool/user/reg', {              method: http.RequestMethod.POST,              header: [                { 'Content-Type': 'application/json' }              ],              extraData: { username: 'jack' }            })              .then((data: http.HttpResponse) => {                // 成功                console.info(JSON.stringify(data.result))              })              .catch((err: BusinessError) => {                // 失败                console.info(err.message)              })              .finally(() => {                // 不管成功失败都销毁请求对象                httpRequest.destroy()              })
复制代码


  • 当前,前端同学可能也更喜欢把Promise的链式调用改成async与await的写法,也是可以的。如下


        Button('发get请求')          .onClick(async () => {            const httpRequest = http.createHttp()            // async和await需要自行用try-catch捕捉错误            try {              // 使用await直接赋值              const data: http.HttpResponse = await httpRequest.request('http://ajax.zll.cool/joke/list', {                extraData: 'num=3'              })              console.info(JSON.stringify(data.result))              } catch (err) {              console.info(JSON.stringify(err))            } finally {              httpRequest.destroy()            }          })
复制代码

使用第三方库 - Axios

  • 没错,大伙一看上面发个请求要这么多步骤。一个对象只能发一个请求,用完还要销毁。是不是觉得很头疼呢?所以真实开发场景下,一般都会对 http 请求做封装,方便自己调用。但是自行封装,需要考虑的情况过多,例如 get 与 post 请求参数格式一般不一样。甚至 post 请求也分 urlencoded 与 josn 格式。自行封装需要做大量判断。并且因为 ArkTS 是强类型语言,还得预定义一些参数类才可。所以这里,猫林老师就暂且不提了。

  • 如果还是想更方便的发请求,不妨使用别人封装好的库。

  • 在鸿蒙开发中,也提供了丰富的第三方库,Axios就是其中之一。

  • Axios

  • 一款异步请求库

  • 使用步骤

  • 项目下载:DevEco 打开项目后,在底部终端,敲入命令


    ohpm install @ohos/axios
复制代码


![image-20240905112837724](https://raw.gitmirror.com/hmzll/typorapic/main//img/202412181144149.png)
复制代码


  • 使用方法


    // get请求    axios.get(url, {                   params: { 参数 }                 })      .then( (res: AxiosResponse) => {              } )      .catch((err: AxiosError) => {                        })                    // post请求    axios.get(url, { 参数 })      .then( (res: AxiosResponse) => {              } )      .catch((err: AxiosError) => {                        })  
复制代码


- 注意:get请求参数因为一般为urlencoded,所以参数处要写`params`,post请求目前而言都是`json`,因此直接传参数- 在axios中,响应结果类型为`AxiosResponse` ,错误类型为`AxiosError`(需导入,利用DevEco提示按回车自动导入)
复制代码



              axios.get('http://ajax.zll.cool/joke/list', { params: { num: 3 } })                .then((res: AxiosResponse) => {                  console.info(JSON.stringify(res.data))                })                .catch((err: AxiosError) => {                  console.info(err.message)                })
复制代码


  • axios 本身就是基于 Promise 封装,因此可以把它改写成asyncawait形式。这里略过,可自行尝试。

  • 非前端出身可能更喜欢用thencatch,无论哪种写法皆可,用自己喜欢的方式

总结

  • 今日主要围绕 http 请求的内容而学习。主要提供两种:1.原生 2.第三方库 axios

  • 如何安装第三方库?


  ohos install 库名
复制代码


用户头像

猫林老师

关注

还未添加个人签名 2024-12-06 加入

还未添加个人简介

评论

发布
暂无评论
鸿蒙应用开发从入门到入行 - 篇7:http网络请求_鸿蒙_猫林老师_InfoQ写作社区