10.23 鸿蒙HTTP数据请求
HTTP请求是客户端与服务器通信的基础,主要包含请求行、请求头、空行和请求体四部分。常见方法包括GET、POST、PUT、DELETE等。在HarmonyOS中实现HTTP请求需导入http模块并申请网络权限,通过createHttp()创建请求对象,使用request()发起请求并处理响应。示例展示了如何请求淘小说数据,包括定义数据类型模型和处理响应结果。开发者需注意请求完成后调用destroy
了解HTTP请求
HTTP(HyperText Transfer Protocol)请求是指客户端(如浏览器、移动应用等)向服务器发送的一种请求,用于获取资源(如网页、图片、视频等)或与服务器进行交互。
1.1 HTTP请求
HTTP 请求是 Web 通信的基础,通常包含以下几个关键部分:
-
请求行(Request Line):
-
包含三个部分:HTTP 方法(如 GET、POST、PUT、DELETE 等)、请求的资源路径(URL)和 HTTP 版本(如 HTTP/1.1)。
-
例如:
GET /index.html HTTP/1.1
-
-
请求头(Request Headers):
-
包含键值对,提供了请求的附加信息,如客户端类型、认证信息、缓存控制等。
-
例如:
-
textCopy Code
-
Host: www.example.comUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
-
-
空行(CRLF):
- 请求头和请求体之间必须有一个空行,这是通过回车(CR)和换行(LF)字符表示的。
-
请求体(Request Body):
-
并非所有请求都包含请求体,主要用于 POST、PUT 等方法,包含了要发送给服务器的数据。
-
例如,一个 POST 请求的体可能包含表单数据或 JSON 对象:
-
textCopy Code
-
{"username": "example","password": "password123"}
-
1.2 常见的 HTTP 方法
-
GET:请求从服务器获取资源。
-
POST:向服务器发送数据,通常用于提交表单或上传文件。
-
PUT:向服务器上传其应在目标资源位置存储的资源的全部内容。
-
DELETE:请求服务器删除指定的资源。
-
HEAD:请求获取与 GET 请求相同的响应,但不返回响应体。
-
OPTIONS:请求描述目标资源的通信选项,通常用于检查服务器支持的 HTTP 方法。
-
PATCH:请求对资源进行部分修改。
1.3 HTTP 响应
服务器接收到 HTTP 请求后,会返回一个 HTTP 响应,包含:
-
状态行(Status Line):
-
包含 HTTP 版本、状态码(如 200、404)和状态消息(如 OK、Not Found)。
-
例如:
HTTP/1.1 200 OK
-
-
响应头(Response Headers):
- 与请求头类似,包含键值对,提供响应的附加信息,如内容类型、服务器类型、缓存控制等。
-
空行(CRLF):
- 响应头和响应体之间必须有一个空行。
-
响应体(Response Body):
- 包含服务器返回的实际数据,如 HTML 文档、JSON 对象、图片等。
通过理解 HTTP 请求和响应的结构,您可以更好地进行 Web 开发、调试和性能优化
实现HTTP请求
2.1 官网文档:
【指南】 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/http-request-V5
【API参考】 https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-http-V5
2.2 导入模块
HTTP数据请求功能主要由http模块提供。
import { http } from '@kit.NetworkKit';
2.3 申请网络权限
使用该功能需要申请ohos.permission.INTERNET权限。
【entry】【src】【main】【module.json5】
{
"module": {
"requestPermissions": [{
//设置申请网络权限
"name": "ohos.permission.INTERNET"
}],
...
}
}
2.4 request接口开发步骤
-
从@kit.NetworkKit中导入http命名空间。
-
调用createHttp()方法,创建一个HttpRequest对象。
-
调用该对象的on()方法,订阅http响应头事件,此接口会比request请求先返回。可以根据业务需要订阅此消息。
-
调用该对象的request()方法,传入http请求的url地址和可选参数,发起网络请求。
-
按照实际业务需要,解析返回结果。
-
调用该对象的off()方法,取消订阅http响应头事件。
-
当该请求使用完毕时,调用destroy()方法主动销毁。
2.5 官网核心代码
![[65dc3b8a-f1bc-4b04-a0f2-0f377023c1ec.png]]
// 引入包名
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 每一个httpRequest对应一个HTTP请求任务,不可复用
let httpRequest = http.createHttp();
// 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
httpRequest.request(
"https://m.taoyuewenhua.com/ajax/book_mall?ctype=1&seed=2580&page=0",
{
// 可选,默认为http.RequestMethod.GET
// http.RequestMethod.POST
method: http.RequestMethod.GET,
// 开发者根据自身业务需要添加header字段
// 下面配置表示接收服务器端传来的json数据
header: { 'Accept': 'application/json' },
// 读取超时时间,可选,默认为60000ms
readTimeout: 60000,
// 连接超时时间,可选,默认为60000ms
connectTimeout: 60000,
},
// 遵循错误优先原则
(err: BusinessError, data: http.HttpResponse) => {
if (!err) {
// data.result为HTTP响应内容,可根据业务需要进行解析
console.info('Result:' + JSON.stringify(data.result));
console.info('code:' + JSON.stringify(data.responseCode));
// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object请求对象。
httpRequest.destroy();
} else {
//请求发生错误时的业务处理
console.info('error:' + JSON.stringify(err));
// 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。
httpRequest.destroy();
}
});
@Entry
@Component
struct Index {
build() {
}
}
2.6 请求淘小说数据
import { http } from '@kit.NetworkKit'
class ResponseResult {
errcode: number;
errmsg: string | Resource;
data: string | Object | ArrayBuffer;
constructor() {
this.errcode = 0;
this.errmsg = '';
this.data = '';
}
}
// bookList数据类型
interface BookItemModel{
title:string,
intro:string,
authorName:string,
coverUrl:string
}
// channelList 数据类型
interface ChannelItemModel {
mcid:number,
title: string,
bookList:BookItemModel[]
}
interface DataModel {
channelList: ChannelItemModel[],
// bannerList: ChannelItemModel[]
}
@Entry
@Component
struct Test {
@State homeData: DataModel = {
channelList: [],
bannerList: []
}
build() {
Column() {
Button("获取淘小说数据")
.onClick(() => {
// 实例化出来了一个对象格式{errorCode:"",errorMsg:"",data:""}
let serverData = new ResponseResult()
let httpRequest = http.createHttp()
httpRequest.request("https://m.taoyuewenhua.com/ajax/book_mall?ctype=1&seed=4724&page=0", {
method: http.RequestMethod.GET,
header: {
"Content-type": "application/json"
}
}, (err, value: http.HttpResponse) => {
if (!err) {
// ----------------------------------------------------------官网代码
// 因为value.result是字符串,但TS不能推理出类型,所以要显示转换为string类型,处理方法用两种
// 第一种
let result = `${value.result}`
let resultJSON: ResponseResult = JSON.parse(result)
// 第二种
// let resultJSON: ResponseResult = JSON.parse(value.result as string)
serverData.data = resultJSON.data
serverData.errcode = resultJSON.errcode
serverData.errmsg = resultJSON.errmsg
// console.log(typeof serverData) // object类型 {"channelList}
this.homeData = serverData.data as DataModel
//-----------------------------------------------------------精简代码
// let result = `${value.result}`
// serverData = JSON.parse(result)
// this.homeData = serverData.data as DataModel
} else {
console.log(JSON.stringify(err))
}
})
})
ForEach(this.homeData.channelList, (item: ChannelItemModel) => {
Row() {
Text(item.title)
}.width('90%').height(50).margin(10).backgroundColor(Color.White)
// 嵌套渲染bookList数据
ForEach(item.bookList,(books:BookItemModel)=>{
Column(){
Text(books.title)
Text(books.authorName)
Text(books.intro)
Text(books.coverUrl)
}
})
}, (item: ChannelItemModel) => item.title)
}
.width('100%')
.height('100%')
.backgroundColor(Color.Gray)
}
}
支持Promise请求的API
![[c01db55e-a786-4f2e-9924-3e20da54aefc.png]]
示例代码1:
import { http } from '@kit.NetworkKit';
class Header {
public contentType: string;
constructor(contentType: string) {
this.contentType = contentType;
}
}
let httpRequest = http.createHttp();
let promise = httpRequest.request("EXAMPLE_URL", {
method: http.RequestMethod.GET,
connectTimeout: 60000,
readTimeout: 60000,
header: new Header('application/json')
});
promise.then((data:http.HttpResponse) => {
console.info('Result:' + data.result);
console.info('code:' + data.responseCode);
}).catch((err:Error) => {
console.info('error:' + JSON.stringify(err));
});
示例代码2
homeDataModel.ets
import { http } from "@kit.NetworkKit";
import { CommonConstants as Const } from '../common/CommonConstants'
export interface BannerItemModel {
mbid: number,
title: string
}
export interface ChannelItemModel {
mbid: number,
title: string,
bookCount: number
}
export interface PageDataModel {
bannerList: BannerItemModel[],
channelList: ChannelItemModel[]
}
export interface ErrorCase {
errCode: number
msg: string
}
export function httpRequestGet(): Promise<PageDataModel> {
return new Promise((resolve, reject) => {
let httpRequest = http.createHttp();
let promise = httpRequest.request("https://m.taoyuewenhua.com/ajax/book_mall?ctype=1&seed=7942&page=0", {
method: http.RequestMethod.GET,
connectTimeout: 60000,
readTimeout: 60000,
header: {
"content-type": 'application/json',
"user-agent": Const.USER_AGENT
}
});
promise
.then((value: http.HttpResponse) => {
// console.info('Result:' + data.result);
// console.info('code:' + data.responseCode);
//处理HTTP状态码,200表求请求成功
if (value.responseCode === 200) {
//请求成功
resolve(JSON.parse(value.result as string).data)
} else {
//请求失败
reject({
errCode: 1,
msg: '网络连接错误'
})
}
})
.catch((err: Error) => {
console.info('error:' + JSON.stringify(err));
});
})
}
MyHttp.ets
import { http } from '@kit.NetworkKit';
import { BannerItemModel, ErrorCase, httpRequestGet, PageDataModel } from '../model/homeDataModel';
@Entry
@Component
struct MyHttp {
@State homeData: PageDataModel = {
bannerList: [],
channelList: []
}
@State isSuccessRequest: boolean = true
//组件初始化
aboutToAppear(): void {
this.getData()
}
//获取数据
getData() {
httpRequestGet()
.then((data: PageDataModel) => {
this.homeData = data
}).catch((err: ErrorCase)=>{
if (err.errCode === 1){
this.isSuccessRequest = false
}
})
}
build() {
Column() {
if (!this.isSuccessRequest) {
// 网络错误
Text("网络连接错误")
} else {
//列表显示
Text("商品列表")
Column() {
ForEach(this.homeData.bannerList, (item: BannerItemModel) => {
Row() {
Text(item.title)
}
}, (item: BannerItemModel) => item.title)
}
}
}
}
}
function ajax(): Promise<string>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
//拿到了接口数据
let data1 = '结果'
resolve(data1)
},1000)
})
}
function task(): Promise<string>{
//第一种方案
return new Promise((resolve,reject)=>{
ajax()
.then((data: string)=>{
console.log('拿到了ajax的结果',data)
resolve(data)
})
})
}
function handleData(){
// 通过调用task拿到"结果"
task().then((data: string)=>{
console.log('终于拿到了',data)
})
}
handleData()
@Entry
@Component
struct Test {
build() {
}
}
function ajax(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
//拿到了接口数据
let data1 = '结果'
resolve(data1)
}, 1000)
})
}
function task() {
//return了promise
return ajax().then((data: string) => {
console.log('拿到了ajax的结果', data)
return data
})
}
function handleData() {
task().then((data)=>{
console.log('拿到了最终的结果',data)
})
}
handleData()
@Entry
@Component
struct Test {
build() {
}
}
新闻发布案例
1. Codelabs地址
https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_NEXT-NewsRelease
![[11cb3ee7-07b9-4081-82aa-6ce2c4dab130.png]]
源码下载和分析
1. gitee地址下载源码
https://gitee.com/harmonyos_codelabs/NewsRelease
![[cb199603-9952-4a23-ada3-c463327227a5.png]]
export default class Constants {
static readonly SERVER: string = 'http://xxx.xxx.xxx.xxx:9588';
static readonly GET_NEWS_TYPE: string = 'news/getNewsType';
static readonly GET_NEWS_LIST: string = 'news/getNewsList';
static readonly UPLOAD_NEWS: string = 'news/addNews';
static readonly UPLOAD_FILE: string = '/files/upload';
static readonly IMAGE_PREFIX: string = '/images/';
static readonly NEWS_EDIT_PAGE: string = 'pages/NewsEditPage'
static readonly SERVER_CODE_SUCCESS: string = 'success';
static readonly Y_OFF_SET_COEFFICIENT: number = 0.1;
static readonly PAGE_SIZE: number = 10;
static readonly CUSTOM_LAYOUT_HEIGHT: number = 70;
static readonly GET_TAB_DATA_CURRENT_PAGE: number = 1;
static readonly HTTP_CODE_200: number = 200;
static readonly DELAY_ANIMATION_DURATION: number = 300;
static readonly DELAY_TIME: number = 1000;
static readonly ANIMATION_DURATION: number = 2000;
static readonly HTTP_READ_TIMEOUT: number = 10000;
static readonly CONTENT_MAX_LINE: number = 3;
static readonly LIST_SPACE: number = 12;
static readonly ITEM_IMG_SPACE: number = 8;
static readonly TYPE_FONT_WEIGHT: number = 700;
static readonly TITLE_FONT_WEIGHT: number = 500;
static readonly DESC_FONT_WEIGHT: number = 400;
static readonly TYPE_ASPECT_RATIO: number = 2;
static readonly DESC_OPACITY: number = 0.6;
static readonly FULL_PERCENT: string = '100%';
static readonly DIVIDER_WIDTH: string = '90%';
static readonly RELEASE_TITLE: string = '新闻发布';
}
export const enum RefreshConstant {
DELAY_PULL_DOWN_REFRESH = 50,
CLOSE_PULL_DOWN_REFRESH_TIME = 150,
DELAY_SHRINK_ANIMATION_TIME = 500
}
export const enum RefreshState {
DropDown = 0,
Release = 1,
Refreshing = 2,
Success = 3,
Fail = 4
}
export const enum PageState {
Loading = 0,
Success = 1,
Fail = 2
}
export const enum UploadingState {
COMPLETE = 'complete',
FAIL = 'fail'
}
export const enum RequestMethod {
POST = 'POST',
GET = 'GET'
}
export const enum ContentType {
JSON = 'application/json',
FORM = 'multipart/form-data'
}
import { http } from '@kit.NetworkKit';
export default class ResponseResult {
code: string;
msg: string | Resource;
data: string | Object | ArrayBuffer;
constructor() {
this.code = '';
this.msg = '';
this.data = '';
}
}
export class NewsData {
title: string = '';
content: string = '';
imagesUrl: Array<NewsFile> = [new NewsFile()];
source: string = '';
}
export class NewsFile {
id: number = 0;
url: | Object | ArrayBuffer = '';
type: number = 0;
newsId: number = 0;
}
export function httpRequestGet(url: string) {
return httpRequest(url, http.RequestMethod.GET);
}
export function httpRequestPost(url: string, newsData: NewsData) {
return httpRequest(url, http.RequestMethod.POST, newsData);
}
function httpRequest(url: string, method: http.RequestMethod, params?: NewsData): Promise<ResponseResult> {
let httpRequest = http.createHttp();
let responseResult = httpRequest.request(url, {
method: method,
readTimeout: Constants.HTTP_READ_TIMEOUT,
header: {
'Content-Type': ContentType.JSON
},
connectTimeout: Constants.HTTP_READ_TIMEOUT,
extraData: params
});
let serverData = new ResponseResult();
// Processes the data and returns.
return responseResult.then((value: http.HttpResponse) => {
if (value.responseCode === Constants.HTTP_CODE_200) {
// Obtains the returned data.
let result = `${value.result}`;
let resultJson: ResponseResult = JSON.parse(result);
if (resultJson.code === Constants.SERVER_CODE_SUCCESS) {
serverData.data = resultJson.data;
}
serverData.code = resultJson.code;
serverData.msg = resultJson.msg;
} else {
serverData.msg = `${$r('app.string.http_error_message')}&${value.responseCode}`;
}
return serverData;
}).catch(() => {
serverData.msg = $r('app.string.http_error_message');
return serverData;
});
}
import NewsTypeBean from './NewsTypeModel'
import ResponseResult from './ResponseResult';
import Constants from '../common/constants/Constants';
import { httpRequestGet } from '../common/utils/HttpUtil';
const DEFAULT_NEWS_TYPES: NewsTypeBean[] = [
new NewsTypeBean(0, $r('app.string.tab_all')),
new NewsTypeBean(1, $r('app.string.tab_domestic')),
new NewsTypeBean(2, $r('app.string.tab_international')),
new NewsTypeBean(3, $r('app.string.tab_fun')),
new NewsTypeBean(4, $r('app.string.tab_military')),
new NewsTypeBean(5, $r('app.string.tab_sports')),
new NewsTypeBean(6, $r('app.string.tab_science'))
];
class NewsTypeViewModel {
/**
* Get news type list from server.
*
* @return NewsTypeBean[] newsTypeList
*/
getNewsTypeList(): Promise<NewsTypeBean[]> {
return new Promise((resolve: Function) => {
let url = `${Constants.SERVER}/${Constants.GET_NEWS_TYPE}`;
httpRequestGet(url).then((data: ResponseResult) => {
if (data.code === Constants.SERVER_CODE_SUCCESS) {
resolve(data.data);
} else {
resolve(DEFAULT_NEWS_TYPES);
}
}).catch(() => {
resolve(DEFAULT_NEWS_TYPES);
});
});
}
/**
* Get default news type list.
*
* @return NewsTypeBean[] newsTypeList
*/
getDefaultTypeList(): NewsTypeBean[] {
return DEFAULT_NEWS_TYPES;
}
}
let newsTypeViewModel = new NewsTypeViewModel();
export default newsTypeViewModel as NewsTypeViewModel;
@Entry
@Component
struct MainPage {
@State tabBarArray: NewsTypeBean[] = NewsTypeViewModel.getDefaultTypeList();
@State currentIndex: number = 0;
@Builder TabBuilder(index: number) {
Column() {
Text(this.tabBarArray[index].name)
.height(Constants.FULL_PERCENT)
.fontSize(this.currentIndex === index ? $r('app.float.bar_selected_font') : $r('app.float.bar_normal_font'))
.fontWeight(this.currentIndex === index ? Constants.TYPE_FONT_WEIGHT : Constants.DESC_FONT_WEIGHT)
.fontColor($r('app.color.title_color'))
}
.padding({ left: $r('app.float.normal_padding'), right: $r('app.float.normal_padding') })
.margin({
left: index === 0 ? $r('app.float.common_padding') : 0,
right: index === this.tabBarArray.length - 1 ? $r('app.float.common_padding') : 0
})
}
aboutToAppear() {
// Request news category.
NewsTypeViewModel.getNewsTypeList().then((typeList: NewsTypeBean[]) => {
this.tabBarArray = typeList;
});
}
部署新闻发布功能的后端服务
- 在源码中找到HttpServerOfNews文件夹
![[9aceea57-effd-4233-9a8d-6c72ee4846dc.png]]
-
把文件夹移动到一个合法的目录中(路径中没有中文或特殊字符)
-
右键,选择用DevEco Studio打开
![[db4371c6-9ff3-481f-b0ec-194b49124522.png]]
- 打开终端
![[aeeeb4c8-9334-4267-a633-8337f9ec4b75.png]]
- 查看是否安装node
在命令行输入 node -v, 如果显示版本号,则已经安装,如果没有,自行安装
node -v
![[4bcd51ae-d36e-4d69-a35d-bb3554541797.png]]、
- 安装项目依赖
npm i // 会按package.json的依赖列表进行安装
- 运行项目
npm start // 运行项目
![[10ccd681-e920-4baf-8db3-ae5f385d3484.png]]
- 在鸿蒙项目中修改以下代码:
// 修改前
static readonly SERVER: string = 'http://XXXXXXX:9588';
//修改后
static readonly SERVER: string = 'http://localhost:9588';
![[aaff72ba-edda-45a8-8ec5-5457fb7f2346.png]]
课前测
需求:
-
封装公共网络请求 (函数 httpRequest)
-
分别封装GET和POST网络请求 (函数 httpRequestGet 和 httpRequestPost)
-
在页面中请求淘小说接口数据
-
用LazyForEach实现bannerList数据的懒加载
-
只能参考官方文档
homeDataModel.ets
import { http } from "@kit.NetworkKit";
import { CommonConstants as Const } from '../common/CommonConstants'
export interface BannerItemModel {
mbid: number,
title: string
}
export interface ChannelItemModel {
mbid: number,
title: string,
bookCount: number
}
export interface PageDataModel {
bannerList: BannerItemModel[],
channelList: ChannelItemModel[]
}
export interface responseResult {
errcode: number,
errmsg: string,
data: PageDataModel
}
export interface ErrorCase {
errCode: number
msg: string
}
export function httpRequestGet(url:string){
return httpRequest(url, http.RequestMethod.GET)
}
export function httpRequestPost(url:string, params?: string){
return httpRequest(url, http.RequestMethod.POST,params )
}
//在get和post请求时都要复用的代码
export function httpRequest(url: string,method: http.RequestMethod, params?: string): Promise<responseResult> {
return new Promise((resolve, reject) => {
let httpRequest = http.createHttp();
let promise = httpRequest.request(url, {
method: method,
connectTimeout: 60000,
readTimeout: 60000,
header: {
"content-type": 'application/json',
"user-agent": Const.USER_AGENT
},
extraData: params
});
promise
.then((value: http.HttpResponse) => {
//处理HTTP状态码,200表求请求成功
if (value.responseCode === 200) {
//请求成功
resolve(JSON.parse(value.result as string))
} else {
reject("错误")
}
})
.catch((err: Error) => {
console.info('error:' + JSON.stringify(err));
});
})
}
BasicDataSource.ets
export class BasicDataSource<T> implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: T[] = [];
public totalCount(): number {
return 0;
}
public getData(index: number): T {
return this.originDataArray[index];
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
}
notifyDatasetChange(operations: DataOperation[]): void {
this.listeners.forEach(listener => {
listener.onDatasetChange(operations);
})
}
}
MyDataSource.ets
import { BasicDataSource } from './BasicDataSource';
import { BannerItemModel } from './homeDataModel';
export class MyDataSource extends BasicDataSource<BannerItemModel> {
private dataArray: BannerItemModel[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): BannerItemModel {
return this.dataArray[index];
}
public pushData(data: BannerItemModel): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
MyHttp.ets
import { BannerItemModel, ErrorCase, httpRequestGet, PageDataModel, responseResult } from '../model/homeDataModel';
import { MyDataSource } from '../model/MyDataSource';
@Entry
@Component
struct MyHttp {
@State homeData: PageDataModel = {
bannerList: [],
channelList: []
}
private lazyHomeData: MyDataSource = new MyDataSource()
//组件初始化
aboutToAppear(): void {
this.getData()
}
//获取数据
getData() {
let url = "https://m.taoyuewenhua.com/ajax/book_mall?ctype=1&seed=200&page=0"
httpRequestGet(url)
.then((data: responseResult) => {
this.homeData = data.data
for (let item of this.homeData.bannerList){
this.lazyHomeData.pushData(item)
}
})
.catch((err: ErrorCase) => {
console.log(err.msg)
})
}
build() {
Column() {
//列表显示
Text("商品列表")
List() {
LazyForEach(this.lazyHomeData, (item: BannerItemModel) => {
ListItem() {
Text(item.title)
}
}, (item: BannerItemModel) => item.title)
}
}
}
}
用函数重载优化请求
ets > common > utils > HttpUtil.ets
import { http } from '@kit.NetworkKit';
import ResponseResult from '../../viewmodel/ResponseResult';
import Constants,{ ContentType} from '../constants/Constants';
//get请求
export function httpRequestGet(url: string) {
return httpRequest(url, http.RequestMethod.GET);
}
// post请求
export function httpRequestPost<T>(url: string, params?: T) {
return httpRequest<T>(url, http.RequestMethod.POST, params);
}
// http请求
function httpRequest(url: string, method: http.RequestMethod): Promise<ResponseResult>
function httpRequest<T>(url: string, method: http.RequestMethod,params?: T): Promise<ResponseResult>
function httpRequest<T>(url: string, method: http.RequestMethod,params?: T): Promise<ResponseResult> {
let httpRequest = http.createHttp();
let responseResult = httpRequest.request(url, {
method: method,
readTimeout: Constants.HTTP_READ_TIMEOUT,
header: {
'Content-Type': ContentType.JSON
},
connectTimeout: Constants.HTTP_READ_TIMEOUT,
extraData: params
});
let serverData = new ResponseResult();
return responseResult.then((value: http.HttpResponse) => {
if (value.responseCode === Constants.HTTP_CODE_200) {
// Obtains the returned data.
let result = `${value.result}`;
let resultJson: ResponseResult = JSON.parse(result);
if (resultJson.errcode === Constants.SERVER_CODE_SUCCESS) {
serverData.data = resultJson.data;
}
serverData.errcode = resultJson.errcode;
serverData.errmsg = resultJson.errmsg;
} else {
serverData.errmsg = `${$r('app.string.http_error_message')}&${value.responseCode}`;
}
return serverData;
}).catch(() => {
serverData.errmsg = $r('app.string.http_error_message');
return serverData;
});
}
更多推荐



所有评论(0)