ToB企服应用市场:ToB评测及商务社交产业平台
标题:
【鸿蒙HarmonyOS】网络哀求http代码实现
[打印本页]
作者:
半亩花草
时间:
2024-9-18 21:07
标题:
【鸿蒙HarmonyOS】网络哀求http代码实现
在网络开发中,HTTP哀求是必不可少的一部分。在鸿蒙(HarmonyOS)开发中,同样需要处置处罚网络哀求,无论是与后端服务器交互照旧获取外部API的数据。下面是对鸿蒙开发中涉及到的HTTP模块——http模块,以及一个常用的第三方库——axios模块的总结。
HTTP协议概述
1.
根本概念
哀求(Request)
:客户端向服务器发送的消息。
响应(Response)
:服务器接收到哀求后返回给客户端的消息。
消息格式
:HTTP消息由报文头(Header)、状态行(Status Line)和可选的实体主体(Entity Body)构成。
2.
哀求报文结构
哀求行
:包含哀求方法、哀求URI和协议版本。
GET /index.html HTTP/1.1
复制代码
哀求头
:包含客户端的信息,如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版本、状态码及状态描述。
HTTP/1.1 200 OK
复制代码
响应头
:包含服务器的信息,如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.
配置和拦截器
loding···
复制代码
【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){}
}
}
}
复制代码
调用封装好的类进行代码实现
loading·····
复制代码
总结
HarmonyOS内置的HTTP模块
:提供了根本的HTTP哀求功能,适合简朴的网络通讯需求。
Axios
:提供了更丰富的功能和更好的用户体验,尤其是对于需要更复杂哀求处置处罚的应用来说,是一个不错的选择。
选择哪个模块取决于你的具体需求和偏好。假如你的应用需要与Web服务细密集成并且需要更多的功能,那么axios大概是更好的选择;而对于简朴的HTTP哀求,HarmonyOS自带的HTTP模块就充足了。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4