1、鸿蒙中如何进行网络请求
1.1 三方库请求
-
@ohos/axios
-
@ohos/retrofit
-
@ohos/httpclient
1.2 鸿蒙原生请求
-
@ohos.net.http
2、ArkTs请求模块@ohos.net.http
本模块提供HTTP数据请求能力。应用可以通过HTTP发起一个数据请求,支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。
3、@ohos.net.http请求流程
-
http.createHttp(创建请求实例任务);
-
request(请求);
-
destroy(中断请求);
-
on(订阅HTTP Response Header 事件);
-
off(取消订阅HTTP Response Header 事件);
-
once(订阅HTTP Response Header 事件,但是只触发一次);
4、预览效果
5、封装@ohos.net.http
5.1 函数式
5.1.1 封装
import http from '@ohos.net.http';export interface httpOptions {timeOut?: number;ContentType?: string;header?: Object;state?: string;callBack?: Function;
}const HTTP_READ_TIMEOUT = 60000;
const HTTP_CONNECT_TIMEOUT = 60000;
const CONTENT_TYPE = 'application/json'export function httpRequest(url: string,method: http.RequestMethod = http.RequestMethod.GET,params?: string | Object | ArrayBuffer,options?: httpOptions
): Promise<ResponseResult> {const request = http.createHttp();// 处理状态if(options?.state) {switch (options.state) {case 'on':request.on('headersReceive', (header) => options.callBack(header));break;case 'once':request.on('headersReceive', (header) => options.callBack(header));break;case 'off':request.off('headersReceive');break;case 'destroy':request.destroy();break;default:break;}return;}// 处理请求const responseResult = request.request(url, {// 超时时间readTimeout: options?.timeOut || HTTP_READ_TIMEOUT,connectTimeout: options?.timeOut || HTTP_CONNECT_TIMEOUT,method,extraData: params || {},header: options?.header || {'Content-Type': options?.ContentType || CONTENT_TYPE},});let serverData: ResponseResult = new ResponseResult();// Processes the data and returns.return responseResult.then((data: http.HttpResponse) => {if (data.responseCode === http.ResponseCode.OK) {// Obtains the returned data.let result = `${data.result}`;let resultJson: ResponseResult = JSON.parse(result);serverData.data = resultJson;serverData.code = 'success';serverData.msg = resultJson?.msg;} else {serverData.msg = `error info & ${data.responseCode}`;}return serverData;}).catch((err) => {serverData.msg = `${err}`;return serverData;})
}export class ResponseResult {/*** Code returned by the network request: success, fail.*/code: string;/*** Message returned by the network request.*/msg: string | Resource;/*** Data returned by the network request.*/data: string | Object | ArrayBuffer;constructor() {this.code = '';this.msg = '';this.data = '';}
}export default httpRequest;
5.1.2 使用
import httpRequest from '../../utils/requestHttp';interface resultType {resultcode: string;reason: string;result: resultValType | null;error_code: string;
}interface resultValType {city: string;realtime: realtimeType;future: Object;
}interface realtimeType {temperature: string;humidity: string;info: string;wid: string;direct: string;power: string;aqi: string;
}@Extend(Text) function textStyle() {.fontColor(Color.White).margin({left: 12})
}@Entry
@Component
struct httpPages {@State html: resultValType = {city: '',realtime: {temperature: '',humidity: '',info: '',wid: '',direct: '',power: '',aqi: '',},future: undefined};@State url: string = "http://apis.juhe.cn/simpleWeather/query?key=397c9db4cb0621ad0313123dab416668&city=西安";@Styles weatherStyle() {.width('100%').padding(6).backgroundColor(Color.Green).borderRadius(8)}build() {Column({space: 10}) {Button("请求数据").onClick(() => {this.httpRequest();})Column() {Text(this.html.city || '--').textStyle().fontWeight(FontWeight.Bold)}.weatherStyle().alignItems(HorizontalAlign.Start)Column() {Text(this.html.realtime.temperature || '--').textStyle()}.weatherStyle().alignItems(HorizontalAlign.Start)Column() {Text(this.html.realtime.humidity || '--').textStyle()}.weatherStyle().alignItems(HorizontalAlign.Start)Column() {Text(this.html.realtime.info || '--').textStyle()}.weatherStyle().alignItems(HorizontalAlign.Start)Column() {Text(this.html.realtime.wid || '--').textStyle()}.weatherStyle().alignItems(HorizontalAlign.Start)Column() {Text(this.html.realtime.direct || '--').textStyle()}.weatherStyle().alignItems(HorizontalAlign.Start)Column() {Text(this.html.realtime.power || '--').textStyle()}.weatherStyle().alignItems(HorizontalAlign.Start)Column() {Text(this.html.realtime.aqi || '--').textStyle()}.weatherStyle().alignItems(HorizontalAlign.Start)}.width('100%').height('100%').padding(10)}private httpRequest() {httpRequest(this.url).then(res => {const data: resultType = res.data as resultType;this.html = data.result;console.info('网络结果:'+JSON.stringify(data));});}
}
5.2 泛型式
5.2.1 封装
import http from '@ohos.net.http';// 1、创建RequestOption.ets 配置类
export interface RequestOptions {url?: string;method?: RequestMethod; // default is GETqueryParams ?: Record<string, string>;extraData?: string | Object | ArrayBuffer;header?: Object; // default is 'content-type': 'application/json'
}export enum RequestMethod {OPTIONS = "OPTIONS",GET = "GET",HEAD = "HEAD",POST = "POST",PUT = "PUT",DELETE = "DELETE",TRACE = "TRACE",CONNECT = "CONNECT"
}/*** Http请求器*/
export class HttpCore {/*** 发送请求* @param requestOption* @returns Promise*/request<T>(requestOption: RequestOptions): Promise<T> {return new Promise<T>((resolve, reject) => {this.sendRequest(requestOption).then((response) => {if (typeof response.result !== 'string') {reject(new Error('Invalid data type'));} else {let bean: T = JSON.parse(response.result);if (bean) {resolve(bean);} else {reject(new Error('Invalid data type,JSON to T failed'));}}}).catch((error) => {reject(error);});});}private sendRequest(requestOption: RequestOptions): Promise<http.HttpResponse> {// 每一个httpRequest对应一个HTTP请求任务,不可复用let httpRequest = http.createHttp();let resolveFunction, rejectFunction;const resultPromise = new Promise<http.HttpResponse>((resolve, reject) => {resolveFunction = resolve;rejectFunction = reject;});if (!this.isValidUrl(requestOption.url)) {return Promise.reject(new Error('url格式不合法.'));}let promise = httpRequest.request(this.appendQueryParams(requestOption.url, requestOption.queryParams), {method: requestOption.method,header: requestOption.header,extraData: requestOption.extraData, // 当使用POST请求时此字段用于传递内容expectDataType: http.HttpDataType.STRING // 可选,指定返回数据的类型});promise.then((response) => {console.info('Result:' + response.result);console.info('code:' + response.responseCode);console.info('header:' + JSON.stringify(response.header));if (http.ResponseCode.OK !== response.responseCode) {throw new Error('http responseCode !=200');}resolveFunction(response);}).catch((err) => {rejectFunction(err);}).finally(() => {// 当该请求使用完毕时,调用destroy方法主动销毁。httpRequest.destroy();})return resultPromise;}private appendQueryParams(url: string, queryParams: Record<string, string>): string {// todo 使用将参数拼接到url上return url;}private isValidUrl(url: string): boolean {//todo 实现URL格式判断return true;}
}// 实例化请求器
const httpCore = new HttpCore();export class HttpManager {private static mInstance: HttpManager;// 防止实例化private constructor() {}static getInstance(): HttpManager {if (!HttpManager.mInstance) {HttpManager.mInstance = new HttpManager();}return HttpManager.mInstance;}request<T>(option: RequestOptions): Promise<T> {return httpCore.request(option);}
}export default HttpManager;
5.2.2 使用
import httpManager, { RequestMethod } from '../../utils/requestManager';interface TestBean {userId: number,id: number,title: string,completed: boolean
}private handleClick() {httpManager.getInstance().request<TestBean>({method: RequestMethod.GET,url: 'https://jsonplaceholder.typicode.com/todos/1' //公开的API}).then((result) => {this.text = JSON.stringify(result);console.info(JSON.stringify(result));}).catch((err) => {console.error(JSON.stringify(err));});}