网络连接
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/net-mgmt-overview-0000001478341009-V2
HTTP数据请求
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/http-request-0000001478061585-V2
应用通过HTTP发起一个数据请求,支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。
HTTP数据请求功能主要由http模块提供。
使用该功能需要申请ohos.permission.INTERNET权限。
权限申请请参考访问控制(权限)开发指导。
涉及的接口如下表,具体的接口说明请参考API文档。
接口名 | 功能描述 |
---|---|
createHttp() | 创建一个http请求。 |
request() | 根据URL地址,发起HTTP网络请求。 |
destroy() | 中断请求任务。 |
on(type: 'headersReceive') | 订阅HTTP Response Header 事件。 |
off(type: 'headersReceive') | 取消订阅HTTP Response Header 事件。 |
once('headersReceive')8+ | 订阅HTTP Response Header 事件,但是只触发一次。 |
request接口开发步骤
- 从@ohos.net.http.d.ts中导入http命名空间。
- 调用createHttp()方法,创建一个HttpRequest对象。
- 调用该对象的on()方法,订阅http响应头事件,此接口会比request请求先返回。可以根据业务需要订阅此消息。
- 调用该对象的request()方法,传入http请求的url地址和可选参数,发起网络请求。
- 按照实际业务需要,解析返回结果。
- 调用该对象的off()方法,取消订阅http响应头事件。
- 当该请求使用完毕时,调用destroy()方法主动销毁。
// 引入包名
import http from '@ohos.net.http';
// 每一个httpRequest对应一个HTTP请求任务,不可复用
let httpRequest = http.createHttp();
// 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
// 从API 8开始,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)。 8+
httpRequest.on('headersReceive', (header) => {
console.info('header: ' + JSON.stringify(header));
});
httpRequest.request(
// 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
"EXAMPLE_URL",
{
method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json'
},
// 当使用POST请求时此字段用于传递内容
extraData: {
"data": "data to send",
},
expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
usingCache: true, // 可选,默认为true
priority: 1, // 可选,默认为1
connectTimeout: 60000, // 可选,默认为60000ms
readTimeout: 60000, // 可选,默认为60000ms
usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
}, (err, data) => {
if (!err) {
// data.result为HTTP响应内容,可根据业务需要进行解析
console.info('Result:' + JSON.stringify(data.result));
console.info('code:' + JSON.stringify(data.responseCode));
// data.header为HTTP响应头,可根据业务需要进行解析
console.info('header:' + JSON.stringify(data.header));
console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
} else {
console.info('error:' + JSON.stringify(err));
// 取消订阅HTTP响应头事件
httpRequest.off('headersReceive');
// 当该请求使用完毕时,调用destroy方法主动销毁
httpRequest.destroy();
}
}
);

案例
现在有这么一个接口: http://127.0.0.1:3000/shops?pageNo=1&&pageSize=4 返回值如下
[
{
"id": 1,
"name": "103茶餐厅",
"images": [
"/images/s3fqawWswzk.jpg",
"/images/aZGOT1OjpJmLxG6urQ.jpg"
],
"area": "大关",
"address": "金华路锦昌文华苑29号",
"avgPrice": 80,
"comments": 3035,
"score": 37,
"openHours": "10:00-22:00"
},
{
"id": 2,
"name": "蔡馬洪涛烤肉·老北京铜锅涮羊肉",
"images": [
"/images/faca41195272.jpg",
"/images/a9f88d706914.jpg",
"/images/jpJmLxG6urQ.jpg"
],
"area": "拱宸桥/上塘",
"address": "上塘路1035号(中国工商银行旁)",
"avgPrice": 85,
"comments": 1460,
"score": 46,
"openHours": "11:30-03:00"
},
{
"id": 3,
"name": "新白鹿餐厅(运河上街店)",
"images": [
"/images/7cgjmzif2w2aalka4gms.jpg",
"/images/73w0k4d40mxjt54btzda.jpg",
"/images/uyb31c7yfqy95dejvis1.jpg"
],
"area": "运河上街",
"address": "台州路2号运河上街购物中心F5",
"avgPrice": 61,
"comments": 8045,
"score": 47,
"openHours": "10:30-21:00"
},
{
"id": 4,
"name": "Mamala(杭州远洋乐堤港店)",
"images": [
"/images/xpm2bq95a3ro2lc4vp5u.jpg",
"/images/7kd3rq9hvtougx3mhnlt.jpg"
],
"area": "拱宸桥/上塘",
"address": "丽水路66号远洋乐堤港商城2期1层B115号",
"avgPrice": 290,
"comments": 9529,
"score": 49,
"openHours": "11:00-22:00"
}
]

//src/main/ets/viewmodel/ShopInfo.ts
export default class ShopInfo {
id: number
name: string
images: string[]
area: string
address: string
avgPrice: number
comments: number
score: number
openHours: string
}
// src/main/ets/model/ShopModel.ts
import http from '@ohos.net.http'
import ShopInfo from '../viewmodel/ShopInfo'
class ShopModel {
pageNo: number = 1
url: string = `http://127.0.0.1:3000/`
getShopList(): Promise<ShopInfo[]> {
return new Promise(
(resolve, reject) => {
let httpRequest = http.createHttp()
httpRequest.request(
this.url + `shops?pageNo=${this.pageNo}&pageSize=4`,
{
method: http.RequestMethod.GET
}
)
.then((res: http.HttpResponse) => {
if (res.responseCode === 200) {
// 请求成功
console.log("Success")
resolve(JSON.parse(res.result.toString()))
}
else {
console.log("Error", JSON.stringify(res))
reject("Error")
}
})
.catch((err: Error) => {
// 请求失败
console.log("Error", JSON.stringify(err))
reject("Error")
})
}
)
}
}
const shopModel = new ShopModel()
export default shopModel as ShopModel
// src/main/ets/views
import ShopInfo from '../viewmodel/ShopInfo'
@Component
export default struct ShopItem {
shop: ShopInfo
build(){
Column({space: 5}){
Row(){
Text(this.shop.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
.ellipsisTextOverFlow()
}
.width('100%')
Row(){
Text(this.shop.address)
.fontColor('#a3a3a3')
.ellipsisTextOverFlow()
}.width('100%')
Row({space: 5}){
Rating({rating: this.shop.score/10 , indicator: true}).stars(5).stepSize(0.1)
Text(`${this.shop.score / 10}`).fontColor('#ffb04d')
Text(`${this.shop.comments}条`).fontColor('#222')
Blank()
Text(`¥${this.shop.avgPrice}/人`)
}.width('100%')
List({space: 10}){
ForEach(this.shop.images, (image) => {
ListItem(){
Column(){
Image(image)
.width(150).aspectRatio(1.1).borderRadius(5)
}
}
})
}
.listDirection(Axis.Horizontal)
.width('100%')
}
.width('100%')
.height(240)
.padding(12)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4})
}
}
// 文本超出时的统一样式处理
@Extend(Text)
function ellipsisTextOverFlow(line: number = 1){
.textOverflow({overflow: TextOverflow.Ellipsis})
.maxLines(line)
}
// src/main/ets/pages/Index.ets
import ShopInfo from '../viewmodel/ShopInfo'
@Component
export default struct ShopItem {
shop: ShopInfo
build(){
Column({space: 5}){
Row(){
Text(this.shop.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
.ellipsisTextOverFlow()
}
.width('100%')
Row(){
Text(this.shop.address)
.fontColor('#a3a3a3')
.ellipsisTextOverFlow()
}.width('100%')
Row({space: 5}){
Rating({rating: this.shop.score/10 , indicator: true}).stars(5).stepSize(0.1)
Text(`${this.shop.score / 10}`).fontColor('#ffb04d')
Text(`${this.shop.comments}条`).fontColor('#222')
Blank()
Text(`¥${this.shop.avgPrice}/人`)
}.width('100%')
List({space: 10}){
ForEach(this.shop.images, (image) => {
ListItem(){
Column(){
Image(image)
.width(150).aspectRatio(1.1).borderRadius(5)
}
}
})
}
.listDirection(Axis.Horizontal)
.width('100%')
}
.width('100%')
.height(240)
.padding(12)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({radius: 6, color: '#1F000000', offsetX: 2, offsetY: 4})
}
}
// 文本超出时的统一样式处理
@Extend(Text)
function ellipsisTextOverFlow(line: number = 1){
.textOverflow({overflow: TextOverflow.Ellipsis})
.maxLines(line)
}
第三方库 axios

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/ide-command-line-ohpm-0000001490235312-V2
OHPM CLI 作为鸿蒙生态三方库的包管理工具,支持OpenHarmony共享包的发布、安装和依赖管理。
下载ohpm工具包,点击链接获取。
解压文件,进入“ohpm/bin”目录,打开命令行工具,执行如下指令
init.bat
初始化ohpm将ohpm配置到环境变量中。
Windows环境变量设置方法:
在此电脑 > 属性 > 高级系统设置 > 高级 > 环境变量中,将ohpm命令行工具的bin目录配置到系统或者用户的PATH变量中。
安装完成之后,执行
ohpm -v
输出版本号即为安装成功
配置完环境变量后可能需要重启电脑才能生效

OpenHarmony三方库中心仓: https://ohpm.openharmony.cn/#/cn/home
以下为 使用案例
// import http from '@ohos.net.http'
import axios from '@ohos/axios'
import ShopInfo from '../viewmodel/ShopInfo'
class ShopModel {
pageNo: number = 1
url: string = `http://127.0.0.1:3000/`
getShopList(): Promise<ShopInfo[]> {
return new Promise(
(resolve, reject) => {
axios.get(
this.url + `shops?pageNo=${this.pageNo}&pageSize=4`,
)
.then((res) => {
if (res.status === 200) {
// 请求成功
console.log("Success")
resolve(res.data)
}
else {
console.log("Error", JSON.stringify(res))
reject("Error")
}
})
.catch((err: Error) => {
// 请求失败
console.log("Error", JSON.stringify(err))
reject("Error")
})
}
)
}
}
const shopModel = new ShopModel()
export default shopModel as ShopModel