ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【鸿蒙HarmonyOS】网络哀求http代码实现 [打印本页]

作者: 半亩花草    时间: 2024-9-18 21:07
标题: 【鸿蒙HarmonyOS】网络哀求http代码实现
在网络开发中,HTTP哀求是必不可少的一部分。在鸿蒙(HarmonyOS)开发中,同样需要处置处罚网络哀求,无论是与后端服务器交互照旧获取外部API的数据。下面是对鸿蒙开发中涉及到的HTTP模块——http模块,以及一个常用的第三方库——axios模块的总结。
HTTP协议概述

1. 根本概念


2. 哀求报文结构


3. 响应报文结构


4. 哀求方法


5. 状态码


HTTP的工作原理

HTTP与HTTPS的区别


通过以上概述,你应该对HTTP协议有了更深入的理解。在实际开发中,根据差别的场景选择合适的哀求方法和状态码,对于构建健壮的网络应用程序至关紧张。
HarmonyOS HTTP模块

官方文档传送门
1. 概述

HarmonyOS提供了内置的http模块来实现HTTP哀求。此模块答应开发者以异步的方式发起HTTP哀求,支持GET、POST等多种HTTP方法。
根本用法

1. 导入

  1. import { http } from '@kit.NetworkKit'
复制代码
2. 创建哀求对象

  1. const req = http.createHttp()
复制代码
3. 发送哀求并获取响应

  1. req.request('请求地址url')
  2.   .then((res: http.HttpResponse) => {
  3.     AlertDialog.show({ message: JSON.stringify(res) })
  4.   })
复制代码
注意事项


  1. {
  2.   "module": {
  3.     "name": "entry",
  4.     "type": "entry",
  5.     "description": "$string:module_desc",
  6.     "mainElement": "EntryAbility",
  7.     "deviceTypes": [
  8.       "phone",
  9.       "tablet",
  10.       "2in1"
  11.     ],
  12.     "deliveryWithInstall": true,
  13.     "installationFree": false,
  14.     "pages": "$profile:main_pages",
  15.     "requestPermissions": [
  16.       {
  17.         "name": "ohos.permission.INTERNET"
  18.       }
  19.     ],
  20.     "abilities": [
  21.       {
  22.         "name": "EntryAbility",
  23.         "srcEntry": "./ets/entryability/EntryAbility.ets",
  24.         "description": "$string:EntryAbility_desc",
  25.         "icon": "$media:icon",
  26.         "label": "$string:EntryAbility_label",
  27.         "startWindowIcon": "$media:startIcon",
  28.         "startWindowBackground": "$color:start_window_background",
  29.         "exported": true,
  30.         "skills": [
  31.           {
  32.             "entities": [
  33.               "entity.system.home"
  34.             ],
  35.             "actions": [
  36.               "action.system.home"
  37.             ]
  38.           }
  39.         ]
  40.       }
  41.     ],
  42.     "extensionAbilities": [
  43.       {
  44.         "name": "EntryBackupAbility",
  45.         "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
  46.         "type": "backup",
  47.         "exported": false,
  48.         "metadata": [
  49.           {
  50.             "name": "ohos.extension.backup",
  51.             "resource": "$profile:backup_config"
  52.           }
  53.         ]
  54.       }
  55.     ]
  56.   }
  57. }
复制代码
  1. // 代码示例import { http } from '@kit.NetworkKit'
  2. const req = http.createHttp()
  3. req.request('请求地址url')
  4.   .then((res: http.HttpResponse) => {
  5.     AlertDialog.show({ message: JSON.stringify(res) })
  6.   })
复制代码
2. 主要方法

   通过一个图书管理案例来详细了解一下http哀求数据的根本使用,因为需要用到接口,我使用的是黑马程序员提供的在线接口文档链接仅供学习
  

完成效果

3. 示例代码

  1. export interface IBook{
  2.   /**
  3.    * 响应数组
  4.    */
  5.   data: iBook[];
  6.   /**
  7.    * 响应消息
  8.    */
  9.   message: string;
  10. }
  11. export interface IBookdetail{
  12.   /**
  13.    * 响应数组
  14.    */
  15.   data: iBook;
  16.   /**
  17.    * 响应消息
  18.    */
  19.   message: string;
  20. }
  21. export interface iBook {
  22.   /**
  23.    * 图书作者
  24.    */
  25.   author: string;
  26.   /**
  27.    * 图书名字
  28.    */
  29.   bookname: string;
  30.   /**
  31.    * 图书id
  32.    */
  33.   id: number;
  34.   /**
  35.    * 图书出版社
  36.    */
  37.   publisher: string;
  38. }
  39. export  const creator='艾宝宝'
复制代码
获取-图书列表 GET &&删除-图书 DELETE
  1. import { IBook, iBook } from './databook'import { http } from '@kit.NetworkKit'
  2. import router from '@ohos.router'import { promptAction } from '@kit.ArkUI'@Entry@Componentstruct MyBook {  @State ISfree: boolean = false  @State books: iBook[] = []  /**   * 页面显示时调用的方法   * 该方法在页面被显示时触发,用于获取书籍信息   */  onPageShow(): void {    // 调用getbook方法获取书籍信息    this.getbook()      // 将返回的效果分析为IBook对象      .then(res => {        let obj: IBook = JSON.parse(res.result.toString())        // 将分析后的书籍数据赋值给books属性        this.books = obj.data      })  }  /**   * 获取书籍信息的方法   * 该方法用于发起网络哀求,获取指定创建者的书籍信息   * @returns 返回一个Promise对象, resolve时携带HTTP响应   */  getbook() {    // 创建HTTP哀求对象    const req = http.createHttp()
  3.     // 发起网络哀求,获取书籍信息    return req.request('https://hmajax.itheima.net/api/books?creator=' + encodeURIComponent('艾宝宝'))  }      //顶部  @Builder  top() {    Row() {      Image($r('app.media.ic_public_drawer_filled'))        .width(30)      //点击弹窗,点击确认全部删除        .onClick(()=>{           promptAction.showDialog({               title: '提示',               message: '确定全部删除吗?',               buttons: [                   { text: '取消', color: '#ff161616' },                   { text: '确认', color: '#ff2156c1' }               ]           }).then(res=>{             // 根据响应的索引实行差别的操作             if (res.index == 1) {               // 创建HTTP哀求对象               const req = http.createHttp()
  4.                // 向指定URL发送DELETE哀求以删除数据               req.request('https://hmajax.itheima.net/api/books', {                 method: http.RequestMethod.DELETE               })                 .then(res => {                   // 分析响应效果,根据id数组中的每个id向服务器发送删除哀求                   this.books.map((item)=>{                     return  req.request('https://hmajax.itheima.net/api/books/' + item.id, {                         method: http.RequestMethod.DELETE                       })                       .then(res => {                         // 分析响应效果,显示提示信息                         let obj: IBook = JSON.parse(res.result.toString())                         promptAction.showToast({                           message: `${obj.message}`                         })                         // 重新获取数据                         this.getbook()                           .then(res => {                             let obj: IBook = JSON.parse(res.result.toString())                             // 更新当地数据                             this.books = obj.data                           })                       })                   })                 })             }           })        })      Text(`我的书架`).fontSize(25)        .fontWeight(FontWeight.Bold)      Image($r('app.media.ic_public_add'))        .width(30)        .onClick(() => {          router.pushUrl({            url: '/pages/addbook'.slice(1)          })        })    }.width('100%')    .padding(10)    .justifyContent(FlexAlign.SpaceBetween)    .border({ width: { bottom: 1 }, color: '#80000000' })  }  //图书列表  @Builder  list() {    List() {      ForEach(this.books, (item: iBook, index: number) => {        ListItem() {          Row({ space: 10 }) {            Image($r('app.media.ic_public_cover'))              .height(100)            Column({ space: 20 }) {              Column({ space: 10 }) {                Text(`书名:` + item.bookname).width('100%').fontWeight(FontWeight.Bold)                  .fontSize(18)                Text(`作者:` + item.author).width('100%')                  .fontSize(14)                  .fontColor('#666666')              }              Text(`出版社:` + item.publisher).width('100%')                .fontSize(14)                .fontColor('#666666')            }            .layoutWeight(1)          }.width('100%').height(100)        }.padding(10)        .swipeAction({ end: this.dle(item.id), })        .onClick(() => {          router.pushUrl({            url: '/pages/alterbook'.slice(1),            params: {              id: item.id            }          })        })      })    }.layoutWeight(1).scrollBar(BarState.Off)  }  //删除图标  @Builder  dle(id: number) {    Column() {      Text(`删除`)        .fontColor('#ffffff')        .fontWeight(FontWeight.Bold)    }.width(70)    .height('100%')    .backgroundColor('red')    .justifyContent(FlexAlign.Center)    .onClick(()=>{     promptAction.showDialog({    title: '提示',    message: '确定删除吗?',    buttons: [        { text: '确定', color: '#ff164ae0' },        { text: '取消', color: '#ff1c1919' }    ]})        .then(res=>{            //AlertDialog.show({message:JSON.stringify(res,null,2)})          //点击确定删除 ---索引次序从0开始 左边是0          if (res.index == 0) {            const req = http.createHttp()
  5.             req.request('https://hmajax.itheima.net/api/books/' + id, {              method: http.RequestMethod.DELETE            })              .then(res => {                let obj: IBook = JSON.parse(res.result.toString())                promptAction.showToast({                  message: `${obj.message}`                })                this.getbook()                  .then(res => {                   let obj: IBook = JSON.parse(res.result.toString())                    this.books = obj.data                  })              })          }        })    })  }  build() {      Column() {        //        this.top()        //正在加载的动画        if (this.books.length == 0) {          this.loading()        }        //        this.list()      }      .padding(10)      .width('100%')      .height('100%')  }  //加载中占位图  @Builder  loading() {    Row() {      LoadingProgress()        .width(50)      Text(`加载中...`)    }  }}
复制代码
新增-图书 POST
  1. // 导入创建者import { creator, IBook } from './databook'import { promptAction, router } from '@kit.ArkUI'import { http } from '@kit.NetworkKit'
  2. /* * 步调 * 1. 非空验证 -> 轻提示用户 * ✔️2. 获取表单的值 -> 已经使用了$$完成 * 3. 发出POST哀求将数据提交给服务器 * 4. 返回图书列表页面 * * */@Entry@Componentstruct addPage {  @State bookname: string = ''  @State author: string = ''  @State publisher: string = ''  // 新增的  addSubmit() {    //  1. 非空验证 -> 轻提示用户    if (this.bookname == '' || this.author == '' || this.publisher == '') {      promptAction.showToast({ message: '图书名,作者,出版社均非空' })      return //阻止下面代码继续实行    }    // 3. 发出POST哀求将数据提交给服务器    const req = http.createHttp()
  3.     req.request('https://hmajax.itheima.net/api/books', {      method: http.RequestMethod.POST,      header: {        'Content-Type': 'application/json'      },      extraData: {        bookname: this.bookname,        author: this.author,        publisher: this.publisher,        creator: creator      }    }).then(res => {      let obj: IBook = JSON.parse(res.result.toString())      // 提示用户新增的效果      promptAction.showToast({ message: obj.message })      // 4. 返回图书列表页面      // ✨✨注意:通过router.back()返回的页面是不会触发aboutToAppear这个函数的      // 需要将其改成 onPageShow ,所以我们需要改造 BookListPage.ets中的生命周期方法      // pushUrl -> 页面栈中每次都新增一个页面,最多只能32个,所以这里使用back方法来节省页面栈      router.back()    })  }  build() {    Navigation() {      Column({ space: 10 }) {        Row() {          Text('图书名称:')          TextInput({ placeholder: '请输入图书名字', text: $$this.bookname })        }        Row() {          Text('图书作者:')          TextInput({ placeholder: '请输入作者名字', text: $$this.author })        }        Row() {          Text('图书出版社:')          TextInput({ placeholder: '请输入出版社名字', text: $$this.publisher })        }        Button({ type: ButtonType.Normal }) {          Text('保存')            .fontColor(Color.White)            .fontWeight(800)        }        .width('100%')        .height(40)        .borderRadius(8)        .onClick(() => {          // 调用新增逻辑方法          this.addSubmit()        })      }      .height('100%')      .width('100%')      .padding(10)    }    .title('新增图书')    .titleMode(NavigationTitleMode.Mini)  }}
复制代码
修改-图书 PUT
  1. import router from '@ohos.router'import { creator, IBook, IBookdetail } from './databook'import { http } from '@kit.NetworkKit'
  2. import { promptAction } from '@kit.ArkUI'interface BookId {  id: number}@Entry@Componentstruct Alterbook {  req = http.createHttp()  @State bookid: number = 0  creator: string = creator  @State bookname: string = ''  @State author: string = ''  @State publisher: string = ''  // 页面加载时,获取图书id,通过id获取图书信息  id(路由传参)  aboutToAppear(): void {    let obj = router.getParams() as BookId    this.bookid = obj.id    this.req.request('https://hmajax.itheima.net/api/books/' + this.bookid, {})      .then(res => {        let book: IBookdetail = JSON.parse(res.result.toString())        this.bookname = book.data.bookname        this.author = book.data.author        this.publisher = book.data.publisher      })  }  // creator: string = creator  build() {    Navigation() {      Column({ space: 10 }) {        Row() {          Text(`图书名称:`)          TextInput({            placeholder: '请输入图书名称', text: $$this.bookname,          }).layoutWeight(1)            .backgroundColor('#fff')        }.border({ width: { bottom: 1 }, color: '#ccc' })        Row() {          Text(`图书作者:`)          TextInput({            placeholder: '请输入图书作者',            text: $$this.author,          }).layoutWeight(1).backgroundColor('#fff')            .backgroundColor('#fff')        }.border({ width: { bottom: 1 }, color: '#ccc' })        Row() {          Text(`图书出版社:`)          TextInput({            placeholder: '请输入出版社',            text: $$this.publisher,          }).layoutWeight(1).backgroundColor('#fff')        }.border({ width: { bottom: 1 }, color: '#ccc' })        Button({ type: ButtonType.Normal }) {          Text(`保存`)            .fontSize(18)            .fontColor('#fff')            .fontWeight(FontWeight.Bold)        }.width('100%').borderRadius(10)        //将页面数据重新发送哀求到服务器,修改完毕        .onClick(() => {          if (this.bookname == '' || this.author == '' || this.publisher == '') {            promptAction.showToast({              message: `请输入完备信息`,              bottom: 350            })          } else {            // 创建一个HTTP哀求对象            const req = http.createHttp()
  3.             // 发送PUT哀求以更新书籍信息            req.request('https://hmajax.itheima.net/api/books/' + this.bookid, {              // 设置哀求方法为PUT              method: http.RequestMethod.PUT,              // 设置哀求头,指定内容类型为JSON              header: {                'content-type': 'application/json'              },              // 设置哀求体,包含需要更新的书籍信息              extraData: {                bookname: this.bookname,                author: this.author,                publisher: this.publisher,                creator: creator              }              // 哀求发送完成后实行的回调函数              // 这里可以处置处罚响应数据大概处置处罚错误            }).then(res => {              let obj: IBook = JSON.parse(res.result.toString())              promptAction.showToast({                message: `${obj.message}`,                bottom: 350              })              router.back()            })          }        })        .height(38)      }.padding(15)    }    .title('编辑图书')    .titleMode(NavigationTitleMode.Mini)  }}
复制代码
Axios模块

1. 概述

Axios 是一个基于Promise的HTTP客户端,可以在浏览器和Node.js中使用。虽然HarmonyOS不是直接支持Node.js环境,但是可以通过npm安装axios并在HarmonyOS的应用中使用。
参考链接
2. 优点


3. 安装

在HarmonyOS应用开发环境中,可以使用npm来安装axios:
  1. # 安装
  2. ohpm i @ohos/axios
  3. # 卸载
  4. ohpm uninstall @ohos/axios
复制代码
使用示例

使用前在demo中entry–>src–>main–>ets–>common–>Common.ets文件中改为正确的服务器所在,在entry–>src–>main–>resources–>rawfile目录下添加正确的证书,才可正常的使用demo。
发起一个 GET 哀求
axios支持泛型参数,由于ArkTS不再支持any类型,需指定参数的具体类型。 如:axios.get<T = any, R = AxiosResponse, D = any>(url)

  1. import axios from '@ohos/axios'
  2. interface userInfo{
  3.   id: number
  4.   name: string,
  5.   phone: number
  6. }
  7. // 向给定ID的用户发起请求
  8. axios.get<userInfo, AxiosResponse<userInfo>, null>('/user?ID=12345')
  9. .then((response: AxiosResponse<userInfo>)=> {
  10.   // 处理成功情况
  11.   console.info("id" + response.data.id)
  12.   console.info(JSON.stringify(response));
  13. })
  14. .catch((error: AxiosError)=> {
  15.   // 处理错误情况
  16.   console.info(JSON.stringify(error));
  17. })
  18. .then(()=> {
  19.   // 总是会执行
  20. });
  21. // 上述请求也可以按以下方式完成(可选)
  22. axios.get<userInfo, AxiosResponse<userInfo>, null>('/user', {
  23.   params: {
  24.     ID: 12345
  25.   }
  26. })
  27. .then((response:AxiosResponse<userInfo>) => {
  28.   console.info("id" + response.data.id)
  29.   console.info(JSON.stringify(response));
  30. })
  31. .catch((error:AxiosError) => {
  32.   console.info(JSON.stringify(error));
  33. })
  34. .then(() => {
  35.   // 总是会执行
  36. });
  37. // 支持async/await用法
  38. async function getUser() {
  39.   try {
  40.         const response:AxiosResponse = await axios.get<string, AxiosResponse<string>, null>(this.getUrl);
  41.         console.log(JSON.stringify(response));
  42.       } catch (error) {
  43.     console.error(JSON.stringify(error));
  44.   }
  45. }
复制代码
发送一个 POST 哀求
  1. interface user {
  2.   firstName: string,
  3.   lastName: string
  4. }
  5.    axios.post<string, AxiosResponse<string>, user>('/user', {
  6.      firstName: 'Fred',
  7.      lastName: 'Flintstone'
  8.    })
  9.    .then((response: AxiosResponse<string>) => {
  10.      console.info(JSON.stringify(response));
  11.    })
  12.    .catch((error) => {
  13.   console.info(JSON.stringify(error));
  14. });
复制代码
发起多个并发哀求
  1. const getUserAccount = ():Promise<AxiosResponse> => {
  2.       return axios.get<string, AxiosResponse<string>, null>('/user/12345');
  3.     }
  4. const getUserPermissions = ():Promise<AxiosResponse> => {
  5.       return axios.get<string, AxiosResponse<string>, null>('/user/12345/permissions');
  6.     }
  7. Promise.all<AxiosResponse>([getUserAccount(), getUserPermissions()])
  8. .then((results:AxiosResponse[]) => {
  9.         const acct = results[0].data as string;
  10.         const perm = results[1].data as string;
  11.       });
复制代码
使用说明

axios API

通过向 axios 传递相干配置来创建哀求

axios(config)

  1. // 发送一个get请求
  2. axios<string, AxiosResponse<string>, null>({
  3.   method: "get",
  4.   url: 'https://www.xxx.com/info'
  5. }).then((res: AxiosResponse) => {
  6.   console.info('result:' + JSON.stringify(res.data));
  7. }).catch((error: AxiosError) => {
  8.   console.error(error.message);
  9. })
复制代码
axios(url[, config])

  1. // 发送一个get请求(默认请求方式)
  2. axios.get<string, AxiosResponse<string>, null>('https://www.xxx.com/info', { params: { key: "value" } })
  3. .then((response: AxiosResponse) => {
  4.   console.info("result:" + JSON.stringify(response.data));
  5. })
  6. .catch((error: AxiosError) => {
  7.   console.error("result:" + error.message);
  8. });
复制代码
哀求方法的 别名方式 来创建哀求

为方便起见,为全部支持的哀求方法提供了别名。

   注意: 在使用别名方法时, url、method、data 这些属性都不必在配置中指定。
  1. // 发送get请求
  2. axios.get<string, AxiosResponse<string>, null>('https://www.xxx.com/info', { params: { key: "value" } })
  3. .then((response: AxiosResponse) => {
  4.   console.info("result:" + JSON.stringify(response.data));
  5. })
  6. .catch((error: AxiosError) => {
  7.   console.error("result:" + error.message);
  8. });
复制代码
axios 实例

创建一个实例

您可以使用自界说配置新建一个实例。
axios.create([config])
  1. const instance = axios.create({
  2.   baseURL: 'https://www.xxx.com/info',
  3.   timeout: 1000,
  4.   headers: {'X-Custom-Header': 'foobar'}
  5. });
复制代码
实例方法


4. 图书案例示例代码–Axios

  1. export interface iBookResponse {
  2.   /**
  3.    * 响应数组
  4.    */
  5.   data: iBookInfo[];
  6.   /**
  7.    * 响应消息
  8.    */
  9.   message: string;
  10. }
  11. export const  creator: string = 'baba'
  12. // 按需导出
  13. export interface iBookInfo {
  14.   /**
  15.    * 图书作者
  16.    */
  17.   author: string;
  18.   /**
  19.    * 图书名字
  20.    */
  21.   bookname: string;
  22.   /**
  23.    * 图书id
  24.    */
  25.   id: number;
  26.   /**
  27.    * 图书出版社
  28.    */
  29.   publisher: string;
  30. }
复制代码
获取-图书列表 GET &&
删除-图书 DELETE

  1. import axios, { AxiosResponse } from '@ohos/axios'
  2. import { iBookResponse, iBookInfo, creator } from './models'
  3. import router from '@ohos.router'
  4. import { promptAction } from '@kit.ArkUI'
  5. const req = axios.create()
  6. @Entry
  7. @Component
  8. struct Index {
  9.   @State bookList: iBookInfo[] = []
  10.   creator: string = creator
  11.   //-------------------------
  12.   onPageShow(): void {
  13.     this.getList()
  14.   }
  15.   //-----------------请求数据渲染到列表
  16.   async getList() {
  17.     // 发起GET请求以获取图书数据
  18.     let res: AxiosResponse<iBookResponse> =
  19.       await req.request({
  20.         url: 'https://hmajax.itheima.net/api/books',
  21.         method: 'get',
  22.         params: {
  23.           creator: creator
  24.         }
  25.       })
  26.     // 将请求响应中的图书数据赋值给bookList属性
  27.     this.bookList = res.data.data
  28.     //AlertDialog.show({message:JSON.stringify(res.data)})
  29.   }
  30.   // 1. 我的书架
  31.   @Builder
  32.   MyBook() {
  33.     Row() {
  34.       Image($r('app.media.ic_public_drawer_filled'))
  35.         .height(20)//---------------点击全部删除
  36.         .onClick(async () => {
  37.           promptAction.showDialog({
  38.             title: '提示',
  39.             message: '确定删除吗?',
  40.             buttons: [
  41.               { text: '确定', color: '#ff164ae0' },
  42.               { text: '取消', color: '#ff1c1919' }
  43.             ]
  44.           }) //根据点击结果,执行不同的操作
  45.           //循环数组,每次根据id删除
  46.          if (res.index == 0) {
  47.           for (let i = 0; i < this.bookList.length; i++) {
  48.             let res: AxiosResponse<iBookResponse> =
  49.               await req.request({
  50.                 url: 'https://hmajax.itheima.net/api/books/' + this.bookList[i].id,
  51.                 method: 'delete'
  52.               })
  53.           }
  54.           }
  55.           //刷新列表 提示
  56.           AlertDialog.show({ message: '全部删除成功' })
  57.           this.getList()
  58.         })
  59.       Text('我的书架')
  60.         .fontSize(20)
  61.         .fontWeight(800)
  62.       Image($r('app.media.ic_public_add'))
  63.         .height(20)
  64.         .onClick(() => {
  65.           router.pushUrl({
  66.             url: '/pages/Mbook/addPage'.slice(1),
  67.           })
  68.         })
  69.     }
  70.     .width('100%')
  71.     .justifyContent(FlexAlign.SpaceBetween)
  72.     .padding(10)
  73.     .border({ width: { bottom: 1 }, color: { bottom: 'rgba(0,0,0,0.2)' } })
  74.   }
  75.   // 2. 书籍列表
  76.   @Builder
  77.   BookList() {
  78.     List() {
  79.       ForEach(this.bookList, (item: iBookInfo, index: number) => {
  80.         ListItem() {
  81.           // 布局
  82.           Row({ space: 10 }) {
  83.             Image($r('app.media.ic_public_cover'))
  84.               .width(100)
  85.             Column({ space: 25 }) {
  86.               Column() {
  87.                 Text('书名:' + item.bookname)
  88.                   .width('100%')
  89.                   .fontSize(20)
  90.                   .fontWeight(800)
  91.                 Text('作者:' + item.author)
  92.                   .width('100%')
  93.                   .fontSize(14)
  94.                   .fontWeight(600)
  95.                   .fontColor('rgba(0,0,0,0.4)')
  96.                   .padding({ top: 5 })
  97.               }
  98.               Text('出版社:' + item.publisher)
  99.                 .width('100%')
  100.                 .fontWeight(600)
  101.                 .fontColor('rgba(0,0,0,0.4)')
  102.             }
  103.             .layoutWeight(1)
  104.           }
  105.           .padding(10)
  106.           //-----------点击跳转编辑
  107.           .onClick(() => {
  108.             router.pushUrl({
  109.               url: 'pages/Mbook/BjPage',
  110.               params: {
  111.                 bookid: item.id
  112.               }
  113.             })
  114.           })
  115.         }
  116.         .swipeAction({
  117.           end: this.delBuilder(item.id)
  118.         })
  119.       })
  120.     }
  121.   }
  122.   // 3. 删除书籍的构建函数
  123.   @Builder
  124.   delBuilder(id: number) {
  125.     Column() {
  126.       Text('删除')
  127.         .backgroundColor(Color.Red)
  128.         .fontColor(Color.White)
  129.         .height('100%')
  130.         .width(60)
  131.         .textAlign(TextAlign.Center)
  132.     }
  133.     .padding(10)
  134.     //点击提示确认删除
  135.     .onClick(() => {
  136.       promptAction.showDialog({
  137.         title: '提示',
  138.         message: '确定删除吗?',
  139.         buttons: [
  140.           { text: '确定', color: '#ff164ae0' },
  141.           { text: '取消', color: '#ff1c1919' }
  142.         ]
  143.       })//根据点击结果,执行不同的操作
  144.         .then(async (res) => {
  145.           if (res.index == 0) {
  146.             //删除
  147.             let res: AxiosResponse<iBookResponse> =
  148.               await req.request({
  149.                 url: 'https://hmajax.itheima.net/api/books/' + id,
  150.                 method: 'delete'
  151.               })
  152.             //删除成功,提示,刷新列表
  153.             promptAction.showToast({
  154.               message: '删除成功'
  155.             })
  156.             this.getList()
  157.           }
  158.         })
  159.     })
  160.   }
  161.   build() {
  162.     Column() {
  163.       // 1. 我的书架
  164.       this.MyBook()
  165.       // 2. 书籍列表
  166.       this.BookList()
  167.     }
  168.     .height('100%')
  169.     .width('100%')
  170.   }
  171. }
复制代码
新增-图书 POST
  1. // 导入创建者
  2. import axios, { AxiosResponse } from '@ohos/axios'
  3. import { creator, iBookInfo, iBookResponse } from './models'
  4. import { promptAction, router } from '@kit.ArkUI';
  5. // POST请求体数据类型
  6. export interface iReqeustBody {
  7.   /**
  8.    * 新增图书作者
  9.    */
  10.   author: string;
  11.   /**
  12.    * 新增图书名字
  13.    */
  14.   bookname: string;
  15.   /**
  16.    * 新增图书创建者,自己的外号,和获取图书时的外号相同
  17.    */
  18.   creator: string;
  19.   /**
  20.    * 新增图书出版社
  21.    */
  22.   publisher: string;
  23. }
  24. @Entry
  25. @Component
  26. struct addPage {
  27.   @State bookname: string = ''
  28.   @State author: string = ''
  29.   @State publisher: string = ''
  30.   creator: string = creator
  31.   build() {
  32.     Navigation() {
  33.       Column({ space: 10 }) {
  34.         Row() {
  35.           Text('图书名称:')
  36.           TextInput({ placeholder: '请输入图书名字', text: $$this.bookname })
  37.         }
  38.         Row() {
  39.           Text('图书作者:')
  40.           TextInput({ placeholder: '请输入作者名字', text: $$this.author })
  41.         }
  42.         Row() {
  43.           Text('图书出版社:')
  44.           TextInput({ placeholder: '请输入出版社名字', text: $$this.publisher })
  45.         }
  46.         Button({ type: ButtonType.Normal }) {
  47.           Text('保存')
  48.             .fontColor(Color.White)
  49.             .fontWeight(800)
  50.         }
  51.         .width('100%')
  52.         .height(40)
  53.         .borderRadius(8)
  54.         //保存更新图书
  55.         .onClick(async () => {
  56.           // 调用接口保存图书
  57.           // 1. 创建一个请求对象
  58.           let req = axios.create()
  59.           // 2. 发送请求
  60.           if (this.bookname == '' || this.author == '' || this.publisher == '') {
  61.             promptAction.showToast({
  62.               message: `请输入完整信息`,
  63.               bottom: 350
  64.             })
  65.           } else {
  66.             let res: AxiosResponse<iBookResponse> =
  67.               await req.request({
  68.                 url: 'https://hmajax.itheima.net/api/books',
  69.                 method: 'post',
  70.                 data: {
  71.                   bookname: this.bookname,
  72.                   author: this.author,
  73.                   publisher: this.publisher,
  74.                   creator: creator
  75.                 } as iReqeustBody
  76.               })
  77.             // 提示  然后返回
  78.             promptAction.showToast({
  79.               message: `${res.data.message}`,
  80.               bottom: 350
  81.             })
  82.             router.back()
  83.           }
  84.         })
  85.       }
  86.       .height('100%')
  87.       .width('100%')
  88.       .padding(10)
  89.     }
  90.     .title('新增图书')
  91.     .titleMode(NavigationTitleMode.Mini)
  92.   }
  93. }
复制代码
修改-图书 PUT
  1. // 导入创建者
  2. import { creator, iBookInfo, iBookResponse, } from './models'
  3. import { router } from '@kit.ArkUI'
  4. import axios, { AxiosResponse } from '@ohos/axios'
  5. interface iRouterParams {
  6.   bookid: number
  7. }
  8. interface iBookInfo1 {
  9.   /**
  10.    * 图书作者
  11.    */
  12.   author: string;
  13.   /**
  14.    * 图书名字
  15.    */
  16.   bookname: string;
  17.   /**
  18.    * 图书创建者,写上自己名字-管理自己的数据
  19.    */
  20.   creator: string;
  21.   /**
  22.    * 图书出版社
  23.    */
  24.   publisher: string;
  25. }
  26. export interface Putbook{
  27. data:iBookInfo1
  28. }
  29. const req = axios.create()
  30. @Entry
  31. @Component
  32. struct addPage {
  33.   @State bookname: string = ''
  34.   @State author: string = ''
  35.   @State publisher: string = ''
  36.   bookid: number = 0
  37.   aboutToAppear(): void {
  38.     //得到传过来的id
  39.     let routerObj = router.getParams() as iRouterParams
  40.     this.bookid = routerObj.bookid
  41.     this.loadBook()
  42.   }
  43.   // 1. 回显图书数据
  44.   async loadBook() {
  45.     try {
  46.       // 此处编写代码
  47.       let res: AxiosResponse<Putbook> = await req.request({
  48.         url: 'https://hmajax.itheima.net/api/books/' + this.bookid,
  49.         method: 'get',
  50.       })
  51.       //AlertDialog.show({message:'获取图书数据成功'})
  52.       this.bookname = res.data.data.bookname
  53.       this.author = res.data.data.author
  54.       this.publisher = res.data.data.publisher
  55.     } catch (err) {
  56.       console.error('err--->', JSON.stringify(err).slice(0,800))
  57.     }
  58.   }
  59.   build() {
  60.     Navigation() {
  61.       Column({ space: 10 }) {
  62.         Row() {
  63.           Text('图书名称:')
  64.           TextInput({ placeholder: this.bookname, text: $$this.bookname })
  65.         }
  66.         Row() {
  67.           Text('图书作者:')
  68.           TextInput({ placeholder: this.author, text: $$this.author })
  69.         }
  70.         Row() {
  71.           Text('图书出版社:')
  72.           TextInput({ placeholder: this.publisher, text: $$this.publisher })
  73.         }
  74.         Button({ type: ButtonType.Normal }) {
  75.           Text('保存')
  76.             .fontColor(Color.White)
  77.             .fontWeight(800)
  78.         }
  79.         .width('100%')
  80.         .height(40)
  81.         .borderRadius(8)
  82. //---------------点击修改并保存数据
  83.         .onClick(async () => {
  84.           let res: AxiosResponse<iBookResponse> =
  85.             await req.request({
  86.             url: 'https://hmajax.itheima.net/api/books/' + this.bookid,
  87.             method: 'put',
  88.             data: {
  89.               bookname: this.bookname,
  90.               author: this.author,
  91.               publisher: this.publisher,
  92.               creator: creator
  93.             } as iBookInfo1
  94.           })
  95.           AlertDialog.show({message:'修改图书数据成功'})
  96.           router.back()
  97.         })
  98.       }
  99.       .height('100%')
  100.       .width('100%')
  101.       .padding(10)
  102.     }
  103.     .title('编辑  图书')
  104.     .titleMode(NavigationTitleMode.Mini)
  105.   }
  106. }
复制代码
5. 配置和拦截器

  1. loding···
复制代码
【http封装】 - 封装request泛型方法

我们发现网络哀求的代码许多,且有些相似之处,我们把GET,POST进行封装之后哀求就变得非常简朴了,我把封装的类放下面:
新建一个.ets文件
loading·····
(更新中···)

  1. import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
  2. import { iLoginUserModel, iResponseModel } from '../models/datamodel'
  3. import { promptAction, router } from '@kit.ArkUI'
  4. // 1. 准备一个axios的对象实例,同时设置好baseUrl
  5. const req = axios.create({
  6. baseURL: 'https://api-harmony-teach.itheima.net/'
  7. })
  8. export class HdHttp {
  9. // 这个方法给外面专门做get请求调用的
  10. static async Get<T>(url: string, paramsOrData?: object) {
  11.   return await HdHttp.request<T>('GET', url, paramsOrData)
  12. }
  13. // 这个方法给外面专门做post请求调用的
  14. static async Post<T>(url: string, paramsOrData?: object) {
  15.   return await HdHttp.request<T>('POST', url, paramsOrData)
  16. }
  17. /*
  18. method:表示服务器的请求方法,Get,POST,PUT,Delete
  19. url:代表的是服务器的url路径(不包含基本域名地址) ,例如:hm/studyInfo
  20. * paramsOrData:请求传参,可选
  21. *
  22. * T:代表的是服务器响应数据中的 data这个属性的类型
  23. * */
  24. private static async request<T>(method: string, url: string, paramsOrData?: object) {
  25.   try {
  26.     //   1. 使用req来发送请求
  27.     let reqConfig: AxiosRequestConfig = {
  28.       method: method,
  29.       url: url, //是请求接口的url路径部分,并且不带有/
  30.     }
  31.     // 2. 分请求类型来决定传参参数是parmas还是data
  32.     if (method == 'GET') {
  33.       reqConfig.params = paramsOrData
  34.     } else {
  35.       reqConfig.data = paramsOrData
  36.     }
  37.     // 3. 在请求前在header中携带token
  38.     // 获取token
  39.     let user = AppStorage.get<iLoginUserModel>('user')
  40.     if (user && user.token) {
  41.       reqConfig.headers = {
  42.         'Authorization': `Bearer ${user.token}`
  43.       }
  44.     }
  45.     let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)
  46.     // 4. 处理服务器响应体中的code值为非10000的情况
  47.     if (res.data.code != 10000) {
  48.       //  将服务器的逻辑问题信息提示给用户
  49.       promptAction.showToast({ message: res.data.message })
  50.       return Promise.reject(res.data.message) //传递给外部调用者的 catch()中的信息
  51.     }
  52.     //   3. 返回结果(返回的是服务器的响应报文体的数据)
  53.     return res.data
  54.   } catch (err) {
  55.     //  当服务器的http状态码为非200,就会执行catch
  56.     let errObj: AxiosError = err
  57.     // 判断服务器的响应状态码如果是401,表示token失效,此时应该提示用户和跳转到登录页面
  58.     if (errObj.response?.status == 401) {
  59.       promptAction.showToast({ message: '登录已失效,请重新登录' })
  60.       router.replaceUrl({ url: 'pages/LoginPage' })
  61.     } else {
  62.       //  提示用户是什么错误即可
  63.       promptAction.showToast({ message: '网络异常:' + errObj.message })
  64.     }
  65.     // AlertDialog.show({ message: 'err:' + JSON.stringify(errObj.response?.status, null, 2) })
  66.     return Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}
  67.   }
  68. }
  69. }
复制代码
调用封装好的类进行代码实现
  1. loading·····
复制代码
总结


选择哪个模块取决于你的具体需求和偏好。假如你的应用需要与Web服务细密集成并且需要更多的功能,那么axios大概是更好的选择;而对于简朴的HTTP哀求,HarmonyOS自带的HTTP模块就充足了。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4