在网络开发中,HTTP哀求是必不可少的一部分。在鸿蒙(HarmonyOS)开发中,同样需要处置处罚网络哀求,无论是与后端服务器交互照旧获取外部API的数据。下面是对鸿蒙开发中涉及到的HTTP模块——http模块,以及一个常用的第三方库——axios模块的总结。
HTTP协议概述
1. 根本概念
- 哀求(Request):客户端向服务器发送的消息。
- 响应(Response):服务器接收到哀求后返回给客户端的消息。
- 消息格式:HTTP消息由报文头(Header)、状态行(Status Line)和可选的实体主体(Entity Body)构成。
2. 哀求报文结构
- 哀求行:包含哀求方法、哀求URI和协议版本。
- 哀求头:包含客户端的信息,如Accept-Language、User-Agent等。
- Accept-Language: zh-CN,zh;q=0.9
- User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3
复制代码 - 实体主体:可选部分,包含哀求的具体内容,如表单数据或文件上传。
- username=admin&password=123456
复制代码 3. 响应报文结构
- 状态行:包含HTTP版本、状态码及状态描述。
- 响应头:包含服务器的信息,如Content-Type、Date等。
- Content-Type: text/html; charset=UTF-8
- Date: Thu, 01 Jan 2023 12:00:00 GMT
复制代码 - 实体主体:可选部分,包含响应的具体内容,如HTML文档。
4. 哀求方法
- GET:哀求指定的资源。
- POST:向指定资源提交数据进行处置处罚哀求(比方提交表单大概注册用户)。
- PUT:更换目标资源。
- DELETE:删除指定资源。
- HEAD:雷同于GET哀求,但只返回头部信息。
- OPTIONS:查询目标资源的通讯选项。
- PATCH:对资源进行部分更新。
5. 状态码
- 1xx(信息响应类):指示哀求已被担当,需要进一步处置处罚。
- 2xx(成功响应类):哀求已成功被服务器接收、理解,并担当。
- 200 OK:成功。
- 201 Created:创建成功。
- 3xx(重定向类):需要客户端接纳进一步的操作来完成哀求。
- 301 Moved Permanently:永久重定向。
- 302 Found:临时重定向。
- 4xx(客户端错误类):哀求中有错误,或哀求无法被服务器理解。
- 400 Bad Request:哀求无效。
- 401 Unauthorized:未经授权。
- 403 Forbidden:禁止访问。
- 404 Not Found:找不到资源。
- 5xx(服务器错误类):服务器在处置处罚哀求的过程中发生了错误。
- 500 Internal Server Error:内部服务器错误。
- 503 Service Unavailable:服务不可用。
HTTP的工作原理
- 建立连接:客户端与服务器之间建立TCP连接。
- 发送哀求:客户端发送HTTP哀求到服务器。
- 处置处罚哀求:服务器接收哀求,处置处罚哀求内容。
- 发送响应:服务器根据处置处罚效果构建响应,并发送给客户端。
- 关闭连接:完成响应后,默认情况下会关闭连接(HTTP/1.0),大概保持连接开放以供后续哀求使用(HTTP/1.1及以上版本)。
HTTP与HTTPS的区别
- 安全性:HTTPS是在HTTP的基础上参加了SSL/TLS协议,用于加密传输的数据,增强安全性。
- 端标语:HTTP默认端口为80,HTTPS默认端口为443。
- 证书:HTTPS需要服务器端有数字证书支持,确保数据的完备性和机密性。
通过以上概述,你应该对HTTP协议有了更深入的理解。在实际开发中,根据差别的场景选择合适的哀求方法和状态码,对于构建健壮的网络应用程序至关紧张。
HarmonyOS HTTP模块
官方文档传送门
1. 概述
HarmonyOS提供了内置的http模块来实现HTTP哀求。此模块答应开发者以异步的方式发起HTTP哀求,支持GET、POST等多种HTTP方法。
根本用法
1. 导入
- import { http } from '@kit.NetworkKit'
复制代码 2. 创建哀求对象
- const req = http.createHttp()
复制代码 3. 发送哀求并获取响应
- req.request('请求地址url')
- .then((res: http.HttpResponse) => {
- AlertDialog.show({ message: JSON.stringify(res) })
- })
复制代码 注意事项
- 预览器:无需配置网络权限即可成功发送哀求。
- 模拟器:需要配置网络权限才能成功发送哀求。
- 真机:需要配置网络权限才能成功发送哀求。
- 在HarmonyOS中,你需要在module.json5文件中配置网络权限。以下是详细的配置示例:
- {
- "module": {
- "name": "entry",
- "type": "entry",
- "description": "$string:module_desc",
- "mainElement": "EntryAbility",
- "deviceTypes": [
- "phone",
- "tablet",
- "2in1"
- ],
- "deliveryWithInstall": true,
- "installationFree": false,
- "pages": "$profile:main_pages",
- "requestPermissions": [
- {
- "name": "ohos.permission.INTERNET"
- }
- ],
- "abilities": [
- {
- "name": "EntryAbility",
- "srcEntry": "./ets/entryability/EntryAbility.ets",
- "description": "$string:EntryAbility_desc",
- "icon": "$media:icon",
- "label": "$string:EntryAbility_label",
- "startWindowIcon": "$media:startIcon",
- "startWindowBackground": "$color:start_window_background",
- "exported": true,
- "skills": [
- {
- "entities": [
- "entity.system.home"
- ],
- "actions": [
- "action.system.home"
- ]
- }
- ]
- }
- ],
- "extensionAbilities": [
- {
- "name": "EntryBackupAbility",
- "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
- "type": "backup",
- "exported": false,
- "metadata": [
- {
- "name": "ohos.extension.backup",
- "resource": "$profile:backup_config"
- }
- ]
- }
- ]
- }
- }
复制代码- // 代码示例import { http } from '@kit.NetworkKit'
- const req = http.createHttp()
- req.request('请求地址url')
- .then((res: http.HttpResponse) => {
- AlertDialog.show({ message: JSON.stringify(res) })
- })
复制代码 2. 主要方法
通过一个图书管理案例来详细了解一下http哀求数据的根本使用,因为需要用到接口,我使用的是黑马程序员提供的在线接口文档链接仅供学习
完成效果
3. 示例代码
- export interface IBook{
- /**
- * 响应数组
- */
- data: iBook[];
- /**
- * 响应消息
- */
- message: string;
- }
- export interface IBookdetail{
- /**
- * 响应数组
- */
- data: iBook;
- /**
- * 响应消息
- */
- message: string;
- }
- export interface iBook {
- /**
- * 图书作者
- */
- author: string;
- /**
- * 图书名字
- */
- bookname: string;
- /**
- * 图书id
- */
- id: number;
- /**
- * 图书出版社
- */
- publisher: string;
- }
- export const creator='艾宝宝'
复制代码 获取-图书列表 GET &&删除-图书 DELETE
- import { IBook, iBook } from './databook'import { http } from '@kit.NetworkKit'
- 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()
- // 发起网络哀求,获取书籍信息 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()
- // 向指定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()
- 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
- // 导入创建者import { creator, IBook } from './databook'import { promptAction, router } from '@kit.ArkUI'import { http } from '@kit.NetworkKit'
- /* * 步调 * 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()
- 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
- import router from '@ohos.router'import { creator, IBook, IBookdetail } from './databook'import { http } from '@kit.NetworkKit'
- 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()
- // 发送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. 优点
- 基于Promise:可以使用async/await语法编写更简洁的异步代码。
- 支持浏览器和Node.js:具有良好的跨平台本领。
- 易于使用:API简朴易懂,文档丰富。
3. 安装
在HarmonyOS应用开发环境中,可以使用npm来安装axios:
- # 安装
- ohpm i @ohos/axios
- # 卸载
- 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)
- T: 是响应数据类型。当发送一个 POST 哀求时,客户端大概会收到一个 JSON 对象。T 就是这个 JSON 对象的类型。默认情况下,T 是 any,这意味着可以接收任何类型的数据。
- R: 是响应体的类型。当服务器返回一个响应时,响应体通常是一个 JSON 对象。R 就是这个 JSON 对象的类型。默认情况下,R 是 AxiosResponse,这意味着响应体是一个 AxiosResponse 对象,它的 data 属性是 T 类型的
- D: 是哀求参数的类型。当发送一个 GET 哀求时,大概会在 URL 中添加一些查询参数。D 就是这些查询参数的类型。参数为空情况下,D 是 null类型。
- import axios from '@ohos/axios'
- interface userInfo{
- id: number
- name: string,
- phone: number
- }
- // 向给定ID的用户发起请求
- axios.get<userInfo, AxiosResponse<userInfo>, null>('/user?ID=12345')
- .then((response: AxiosResponse<userInfo>)=> {
- // 处理成功情况
- console.info("id" + response.data.id)
- console.info(JSON.stringify(response));
- })
- .catch((error: AxiosError)=> {
- // 处理错误情况
- console.info(JSON.stringify(error));
- })
- .then(()=> {
- // 总是会执行
- });
- // 上述请求也可以按以下方式完成(可选)
- axios.get<userInfo, AxiosResponse<userInfo>, null>('/user', {
- params: {
- ID: 12345
- }
- })
- .then((response:AxiosResponse<userInfo>) => {
- console.info("id" + response.data.id)
- console.info(JSON.stringify(response));
- })
- .catch((error:AxiosError) => {
- console.info(JSON.stringify(error));
- })
- .then(() => {
- // 总是会执行
- });
- // 支持async/await用法
- async function getUser() {
- try {
- const response:AxiosResponse = await axios.get<string, AxiosResponse<string>, null>(this.getUrl);
- console.log(JSON.stringify(response));
- } catch (error) {
- console.error(JSON.stringify(error));
- }
- }
复制代码 发送一个 POST 哀求
- interface user {
- firstName: string,
- lastName: string
- }
- axios.post<string, AxiosResponse<string>, user>('/user', {
- firstName: 'Fred',
- lastName: 'Flintstone'
- })
- .then((response: AxiosResponse<string>) => {
- console.info(JSON.stringify(response));
- })
- .catch((error) => {
- console.info(JSON.stringify(error));
- });
复制代码 发起多个并发哀求
- const getUserAccount = ():Promise<AxiosResponse> => {
- return axios.get<string, AxiosResponse<string>, null>('/user/12345');
- }
- const getUserPermissions = ():Promise<AxiosResponse> => {
- return axios.get<string, AxiosResponse<string>, null>('/user/12345/permissions');
- }
- Promise.all<AxiosResponse>([getUserAccount(), getUserPermissions()])
- .then((results:AxiosResponse[]) => {
- const acct = results[0].data as string;
- const perm = results[1].data as string;
- });
复制代码 使用说明
axios API
通过向 axios 传递相干配置来创建哀求
axios(config)
- // 发送一个get请求
- axios<string, AxiosResponse<string>, null>({
- method: "get",
- url: 'https://www.xxx.com/info'
- }).then((res: AxiosResponse) => {
- console.info('result:' + JSON.stringify(res.data));
- }).catch((error: AxiosError) => {
- console.error(error.message);
- })
复制代码 axios(url[, config])
- // 发送一个get请求(默认请求方式)
- axios.get<string, AxiosResponse<string>, null>('https://www.xxx.com/info', { params: { key: "value" } })
- .then((response: AxiosResponse) => {
- console.info("result:" + JSON.stringify(response.data));
- })
- .catch((error: AxiosError) => {
- console.error("result:" + error.message);
- });
复制代码 哀求方法的 别名方式 来创建哀求
为方便起见,为全部支持的哀求方法提供了别名。
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
注意: 在使用别名方法时, url、method、data 这些属性都不必在配置中指定。
- // 发送get请求
- axios.get<string, AxiosResponse<string>, null>('https://www.xxx.com/info', { params: { key: "value" } })
- .then((response: AxiosResponse) => {
- console.info("result:" + JSON.stringify(response.data));
- })
- .catch((error: AxiosError) => {
- console.error("result:" + error.message);
- });
复制代码 axios 实例
创建一个实例
您可以使用自界说配置新建一个实例。
axios.create([config])
- const instance = axios.create({
- baseURL: 'https://www.xxx.com/info',
- timeout: 1000,
- headers: {'X-Custom-Header': 'foobar'}
- });
复制代码 实例方法
- axios#request(config)
- axios#get(url[, config])
- axios#delete(url[, config])
- axios#post(url[, data[, config]])
- axios#put(url[, data[, config]])
4. 图书案例示例代码–Axios
- export interface iBookResponse {
- /**
- * 响应数组
- */
- data: iBookInfo[];
- /**
- * 响应消息
- */
- message: string;
- }
- export const creator: string = 'baba'
- // 按需导出
- export interface iBookInfo {
- /**
- * 图书作者
- */
- author: string;
- /**
- * 图书名字
- */
- bookname: string;
- /**
- * 图书id
- */
- id: number;
- /**
- * 图书出版社
- */
- publisher: string;
- }
复制代码 获取-图书列表 GET &&
删除-图书 DELETE
- import axios, { AxiosResponse } from '@ohos/axios'
- import { iBookResponse, iBookInfo, creator } from './models'
- import router from '@ohos.router'
- import { promptAction } from '@kit.ArkUI'
- const req = axios.create()
- @Entry
- @Component
- struct Index {
- @State bookList: iBookInfo[] = []
- creator: string = creator
- //-------------------------
- onPageShow(): void {
- this.getList()
- }
- //-----------------请求数据渲染到列表
- async getList() {
- // 发起GET请求以获取图书数据
- let res: AxiosResponse<iBookResponse> =
- await req.request({
- url: 'https://hmajax.itheima.net/api/books',
- method: 'get',
- params: {
- creator: creator
- }
- })
- // 将请求响应中的图书数据赋值给bookList属性
- this.bookList = res.data.data
- //AlertDialog.show({message:JSON.stringify(res.data)})
- }
- // 1. 我的书架
- @Builder
- MyBook() {
- Row() {
- Image($r('app.media.ic_public_drawer_filled'))
- .height(20)//---------------点击全部删除
- .onClick(async () => {
- promptAction.showDialog({
- title: '提示',
- message: '确定删除吗?',
- buttons: [
- { text: '确定', color: '#ff164ae0' },
- { text: '取消', color: '#ff1c1919' }
- ]
- }) //根据点击结果,执行不同的操作
- //循环数组,每次根据id删除
- if (res.index == 0) {
- for (let i = 0; i < this.bookList.length; i++) {
- let res: AxiosResponse<iBookResponse> =
- await req.request({
- url: 'https://hmajax.itheima.net/api/books/' + this.bookList[i].id,
- method: 'delete'
- })
- }
- }
- //刷新列表 提示
- AlertDialog.show({ message: '全部删除成功' })
- this.getList()
- })
- Text('我的书架')
- .fontSize(20)
- .fontWeight(800)
- Image($r('app.media.ic_public_add'))
- .height(20)
- .onClick(() => {
- router.pushUrl({
- url: '/pages/Mbook/addPage'.slice(1),
- })
- })
- }
- .width('100%')
- .justifyContent(FlexAlign.SpaceBetween)
- .padding(10)
- .border({ width: { bottom: 1 }, color: { bottom: 'rgba(0,0,0,0.2)' } })
- }
- // 2. 书籍列表
- @Builder
- BookList() {
- List() {
- ForEach(this.bookList, (item: iBookInfo, index: number) => {
- ListItem() {
- // 布局
- Row({ space: 10 }) {
- Image($r('app.media.ic_public_cover'))
- .width(100)
- Column({ space: 25 }) {
- Column() {
- Text('书名:' + item.bookname)
- .width('100%')
- .fontSize(20)
- .fontWeight(800)
- Text('作者:' + item.author)
- .width('100%')
- .fontSize(14)
- .fontWeight(600)
- .fontColor('rgba(0,0,0,0.4)')
- .padding({ top: 5 })
- }
- Text('出版社:' + item.publisher)
- .width('100%')
- .fontWeight(600)
- .fontColor('rgba(0,0,0,0.4)')
- }
- .layoutWeight(1)
- }
- .padding(10)
- //-----------点击跳转编辑
- .onClick(() => {
- router.pushUrl({
- url: 'pages/Mbook/BjPage',
- params: {
- bookid: item.id
- }
- })
- })
- }
- .swipeAction({
- end: this.delBuilder(item.id)
- })
- })
- }
- }
- // 3. 删除书籍的构建函数
- @Builder
- delBuilder(id: number) {
- Column() {
- Text('删除')
- .backgroundColor(Color.Red)
- .fontColor(Color.White)
- .height('100%')
- .width(60)
- .textAlign(TextAlign.Center)
- }
- .padding(10)
- //点击提示确认删除
- .onClick(() => {
- promptAction.showDialog({
- title: '提示',
- message: '确定删除吗?',
- buttons: [
- { text: '确定', color: '#ff164ae0' },
- { text: '取消', color: '#ff1c1919' }
- ]
- })//根据点击结果,执行不同的操作
- .then(async (res) => {
- if (res.index == 0) {
- //删除
- let res: AxiosResponse<iBookResponse> =
- await req.request({
- url: 'https://hmajax.itheima.net/api/books/' + id,
- method: 'delete'
- })
- //删除成功,提示,刷新列表
- promptAction.showToast({
- message: '删除成功'
- })
- this.getList()
- }
- })
- })
- }
- build() {
- Column() {
- // 1. 我的书架
- this.MyBook()
- // 2. 书籍列表
- this.BookList()
- }
- .height('100%')
- .width('100%')
- }
- }
复制代码 新增-图书 POST
- // 导入创建者
- import axios, { AxiosResponse } from '@ohos/axios'
- import { creator, iBookInfo, iBookResponse } from './models'
- import { promptAction, router } from '@kit.ArkUI';
- // POST请求体数据类型
- export interface iReqeustBody {
- /**
- * 新增图书作者
- */
- author: string;
- /**
- * 新增图书名字
- */
- bookname: string;
- /**
- * 新增图书创建者,自己的外号,和获取图书时的外号相同
- */
- creator: string;
- /**
- * 新增图书出版社
- */
- publisher: string;
- }
- @Entry
- @Component
- struct addPage {
- @State bookname: string = ''
- @State author: string = ''
- @State publisher: string = ''
- creator: string = creator
- 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(async () => {
- // 调用接口保存图书
- // 1. 创建一个请求对象
- let req = axios.create()
- // 2. 发送请求
- if (this.bookname == '' || this.author == '' || this.publisher == '') {
- promptAction.showToast({
- message: `请输入完整信息`,
- bottom: 350
- })
- } else {
- let res: AxiosResponse<iBookResponse> =
- await req.request({
- url: 'https://hmajax.itheima.net/api/books',
- method: 'post',
- data: {
- bookname: this.bookname,
- author: this.author,
- publisher: this.publisher,
- creator: creator
- } as iReqeustBody
- })
- // 提示 然后返回
- promptAction.showToast({
- message: `${res.data.message}`,
- bottom: 350
- })
- router.back()
- }
- })
- }
- .height('100%')
- .width('100%')
- .padding(10)
- }
- .title('新增图书')
- .titleMode(NavigationTitleMode.Mini)
- }
- }
复制代码 修改-图书 PUT
- // 导入创建者
- import { creator, iBookInfo, iBookResponse, } from './models'
- import { router } from '@kit.ArkUI'
- import axios, { AxiosResponse } from '@ohos/axios'
- interface iRouterParams {
- bookid: number
- }
- interface iBookInfo1 {
- /**
- * 图书作者
- */
- author: string;
- /**
- * 图书名字
- */
- bookname: string;
- /**
- * 图书创建者,写上自己名字-管理自己的数据
- */
- creator: string;
- /**
- * 图书出版社
- */
- publisher: string;
- }
- export interface Putbook{
- data:iBookInfo1
- }
- const req = axios.create()
- @Entry
- @Component
- struct addPage {
- @State bookname: string = ''
- @State author: string = ''
- @State publisher: string = ''
- bookid: number = 0
- aboutToAppear(): void {
- //得到传过来的id
- let routerObj = router.getParams() as iRouterParams
- this.bookid = routerObj.bookid
- this.loadBook()
- }
- // 1. 回显图书数据
- async loadBook() {
- try {
- // 此处编写代码
- let res: AxiosResponse<Putbook> = await req.request({
- url: 'https://hmajax.itheima.net/api/books/' + this.bookid,
- method: 'get',
- })
- //AlertDialog.show({message:'获取图书数据成功'})
- this.bookname = res.data.data.bookname
- this.author = res.data.data.author
- this.publisher = res.data.data.publisher
- } catch (err) {
- console.error('err--->', JSON.stringify(err).slice(0,800))
- }
- }
- build() {
- Navigation() {
- Column({ space: 10 }) {
- Row() {
- Text('图书名称:')
- TextInput({ placeholder: this.bookname, text: $$this.bookname })
- }
- Row() {
- Text('图书作者:')
- TextInput({ placeholder: this.author, text: $$this.author })
- }
- Row() {
- Text('图书出版社:')
- TextInput({ placeholder: this.publisher, text: $$this.publisher })
- }
- Button({ type: ButtonType.Normal }) {
- Text('保存')
- .fontColor(Color.White)
- .fontWeight(800)
- }
- .width('100%')
- .height(40)
- .borderRadius(8)
- //---------------点击修改并保存数据
- .onClick(async () => {
- let res: AxiosResponse<iBookResponse> =
- await req.request({
- url: 'https://hmajax.itheima.net/api/books/' + this.bookid,
- method: 'put',
- data: {
- bookname: this.bookname,
- author: this.author,
- publisher: this.publisher,
- creator: creator
- } as iBookInfo1
- })
- AlertDialog.show({message:'修改图书数据成功'})
- router.back()
- })
- }
- .height('100%')
- .width('100%')
- .padding(10)
- }
- .title('编辑 图书')
- .titleMode(NavigationTitleMode.Mini)
- }
- }
复制代码 5. 配置和拦截器
【http封装】 - 封装request泛型方法
我们发现网络哀求的代码许多,且有些相似之处,我们把GET,POST进行封装之后哀求就变得非常简朴了,我把封装的类放下面:
新建一个.ets文件
loading·····
(更新中···)
- import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
- import { iLoginUserModel, iResponseModel } from '../models/datamodel'
- import { promptAction, router } from '@kit.ArkUI'
- // 1. 准备一个axios的对象实例,同时设置好baseUrl
- const req = axios.create({
- baseURL: 'https://api-harmony-teach.itheima.net/'
- })
- export class HdHttp {
- // 这个方法给外面专门做get请求调用的
- static async Get<T>(url: string, paramsOrData?: object) {
- return await HdHttp.request<T>('GET', url, paramsOrData)
- }
- // 这个方法给外面专门做post请求调用的
- static async Post<T>(url: string, paramsOrData?: object) {
- return await HdHttp.request<T>('POST', url, paramsOrData)
- }
- /*
- method:表示服务器的请求方法,Get,POST,PUT,Delete
- url:代表的是服务器的url路径(不包含基本域名地址) ,例如:hm/studyInfo
- * paramsOrData:请求传参,可选
- *
- * T:代表的是服务器响应数据中的 data这个属性的类型
- * */
- private static async request<T>(method: string, url: string, paramsOrData?: object) {
- try {
- // 1. 使用req来发送请求
- let reqConfig: AxiosRequestConfig = {
- method: method,
- url: url, //是请求接口的url路径部分,并且不带有/
- }
- // 2. 分请求类型来决定传参参数是parmas还是data
- if (method == 'GET') {
- reqConfig.params = paramsOrData
- } else {
- reqConfig.data = paramsOrData
- }
- // 3. 在请求前在header中携带token
- // 获取token
- let user = AppStorage.get<iLoginUserModel>('user')
- if (user && user.token) {
- reqConfig.headers = {
- 'Authorization': `Bearer ${user.token}`
- }
- }
- let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)
- // 4. 处理服务器响应体中的code值为非10000的情况
- if (res.data.code != 10000) {
- // 将服务器的逻辑问题信息提示给用户
- promptAction.showToast({ message: res.data.message })
- return Promise.reject(res.data.message) //传递给外部调用者的 catch()中的信息
- }
- // 3. 返回结果(返回的是服务器的响应报文体的数据)
- return res.data
- } catch (err) {
- // 当服务器的http状态码为非200,就会执行catch
- let errObj: AxiosError = err
- // 判断服务器的响应状态码如果是401,表示token失效,此时应该提示用户和跳转到登录页面
- if (errObj.response?.status == 401) {
- promptAction.showToast({ message: '登录已失效,请重新登录' })
- router.replaceUrl({ url: 'pages/LoginPage' })
- } else {
- // 提示用户是什么错误即可
- promptAction.showToast({ message: '网络异常:' + errObj.message })
- }
- // AlertDialog.show({ message: 'err:' + JSON.stringify(errObj.response?.status, null, 2) })
- return Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}
- }
- }
- }
复制代码 调用封装好的类进行代码实现
总结
- HarmonyOS内置的HTTP模块:提供了根本的HTTP哀求功能,适合简朴的网络通讯需求。
- Axios:提供了更丰富的功能和更好的用户体验,尤其是对于需要更复杂哀求处置处罚的应用来说,是一个不错的选择。
选择哪个模块取决于你的具体需求和偏好。假如你的应用需要与Web服务细密集成并且需要更多的功能,那么axios大概是更好的选择;而对于简朴的HTTP哀求,HarmonyOS自带的HTTP模块就充足了。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |