In the development of the HarmonyOS application, the @ohos.net.http module that is officially provided can be used to access the network through HTTP. However, the official direct use is not very easy to use and needs to be packaged. It is recommended to use the popular axios network client library in front-end development. If it is the front-end developer, it will be easier to use axios.
Catalog
Introduction to axios
Can also use Axios? in HarmonyOS
Using the axios Network Request Library
Download Install
Activate permissions
Simple to use
Package and use of the axios module
Client encapsulation
Use after encapsulation
Official @ohos/net.http Introduction
Official Easy Package
Official http Module Package Use
Written at the end
Additional Resources
Introduction to axios
Axios is a well-known JavaScript-based open source library for sending HTTP requests in environments such as browsers and Node.js. It supports Promise API and can handle the complexity behind XMLHttpRequests and Fetch API, providing developers with a simple and easy-to-use way to implement Ajax (Asynchronous JavaScript and XML) requests.
The earliest browser page requests data from the server and returns the data of the whole page. The page will be refreshed forcibly, which is not very friendly to the user. We only want to modify some data of the page, but the whole page is returned from the server. So a new technology appeared, asynchronous network request Ajax, Asynchronous JavaScript and XML, it can exchange a small amount of data with the background server, so that the web page realizes asynchronous local update.
Because the native XMLHttpRequest API in the browser is more difficult to use, there are more javascript frameworks for implementing ajax, such as the familiar jQuery, Dojo, YUI, and so on. Today, a lightweight framework, called axios, is emerging as essentially a package for native XHR, except that it is an implementation version of Promise that meets the latest ESs specifications.
Key Features:
- Cross-platform support: The Axios can send requests through the XMLHttpRequests on the browser side, and use the http/https module in the Node.js.
- Promise API: All Axios network request methods return Promise objects, making asynchronous programming simpler and easier to handle.
- Intercept requests and responses: Provides global and instance-level interceptors for requests and responses, which can perform operations such as preprocessing, error processing, or data conversion before the request is sent or after the response is returned.
- Cancel Request: Supports active cancellation of an HTTP request that has been issued but not yet completed.
- Automatically convert JSON data: The Axios automatically converts the JSON data from the server into JavaScript objects, and automatically serializes the JSON data in the POST, PUT, and other request bodies into a string for sending.
- Configuration flexibility: The Axios allows you to customize various configuration items such as request headers, URLs, and timeout periods, which are applicable to different scenarios.
- Multiple request methods: Support all standard HTTP methods (GET, POST, PUT, DELETE, etc.) and good support for non-standard methods such as PATCH.
- Upload and download progress monitoring: The Axios also monitors the progress events of file uploading and downloading.
Can also use Axios? in HarmonyOS
In HarmonyOS, the @ohos/net.http module is officially available for network access. It is an official basic HTTP data request capability library. It directly supports the bottom layer of the HTTP protocol. Developers can send HTTP requests such as GET and POST through this module and process response results. Because it is a system-level API, its advantages are that performance and compatibility are guaranteed, and it is suitable for basic HTTP communication requirements.
Although @ohos/net.http modules are officially available for network access, the Axios library can be seen as a more powerful and easy-to-use package, and the interface usage is more consistent with the habits of front-end developers. The Axios library has become a popular client-side library in modern JavaScript applications due to its powerful functionality and ease of use.
To use the original axios library directly, the module name of the Axios library in the HarmonyOS is @ohos/axios.
The @ohos/axios third-party library is adapted based on the axios library, so that it can run in a network request library in the OpenHarmony, and this library follows the existing usage and features of the axios library, so that it is more suitable for the development of the Hongmeng project.
The @ohos/axios module may be understood as an encapsulation or extension of the official HTTP API. The @ohos/axios module provides a higher level of abstraction and convenience, and may include more functional features, such as automatic data format conversion, error processing, an interceptor mechanism, and good support for the Promise. This is to simplify a development process and improve development efficiency. When actually developing an application, if you need richer and more flexible network request management functions, it is usually recommended to use an encapsulation library such as @ohos/axios.
Through the check of the @ohos/axis source code, it is found that the ohos.net.http module is used to adapt the v1.3.4 version of the original library, so that it can be applied to the HarmonyOS and its existing usage and features are followed.
- Http Request
- Promise API
- Request and response interceptors
- Convert data data for request and response
- Automatically convert JSON data data
Ohos/axios module source code:
OpenHarmony-SIG/ohos_axios
Using the axios Network Request Library
Interface List
|Interface| parameter | Function |
| — | — | — |
| axios(config) | config:Request configuration | send request |
| axios.create(config) | config:Request configuration | Create instance |
| axios.request(config) | config:Request configuration | send request |
| axios.get(url[, config]) | Url: Request Address
Config: Request Configuration Send get Request
| axios.delete(url[, config]) | Url: Request Address
Config: Request Configuration Send delete Request
| axios.post(url[, data[, config]]) | Url: Request Address
Data: Sending Request Volume Data
Config: Request Configuration Send post Request
| axios.put(url[, data[, config]]) | Url: Request Address
Data: Sending Request Volume Data
Config: Request Configuration Send put Request
Attribute List
|Properties| describe |
| — | — |
| axios.defaults[’xxx’] | Default settings. Value is the configuration item in the request configuration config
For example, the axios.defaults.headers obtains the header information.
| axios.interceptors | Interceptor。reference Interceptor usage of |
Download Install
- Mode 1: In the terminal window, run the following command to install the three-party package. The DevEco Studio automatically adds the three-party package dependency in the oh-package.json5 of the project.
ohpm install @ohos/axis
If no ohpm command is prompted, the environment variable is not configured. Click the Configure ohpm command to view the detailed configuration.
- Manner 2: Set the three-party package dependency in the oh-package.json5 of the project. The configuration example is as follows:
"dependencies": { "@ohos/axis": "^2.1.0"}
Activate permissions
Ohos.permission.INTERNET permissions need to be configured. Locate the module.json5 file in the project directory entry\src\main and configure the network request permissions.
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone"
],
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
Simple to use
import axios from '@ohos/axios'
//createaxiosExample of
const instance = axios.create({
baseURL: "http://xx.xx.xx.xx", //base path,Want to seeAPIFeatures of the help document to determine the base path
timeout: 5000, //Request timeout time
headers: {
"Content-Type": "application/json"
}
})
//response interceptor,Further process the returned data through the response interceptor
instance.interceptors.response.use((response) => {
//Only return results if the interface has data
if (200 === response.status) {
return response.data; //Data returned by the interface
}
return Promise.reject(response); //Indicates an error in the request,hand overcatchto handle the structure
}, err => {
return Promise.reject(err)
})
/**
* getask
* @param params = {} query parameters
* @returns
*/
export function httpGet(url:string, params = {}) {
return instance.get<any>(url, {
params
})
}
/**
* postask
* @param data = {} Request body data
* @returns
*/
export function httpPost(url:string, data = {}) {
return instance.post<any>(url, {
data
})
}
Package and use of the axios module
Axios module package:
//AxiosHttp.ets
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosRequestHeaders,
AxiosResponse,
InternalAxiosRequestConfig
} from "@ohos/axios";
import { LogUtils } from '../utils/LogUtils';
/**
* Define interface response wrapper class
*/
export interface BaseResponse {
//wanAndroid-APIresponse body
errorCode: number
errorMsg: string
//expandxxx-APIresponse body
}
/**
* Interface implementation class packaging,For example, other businesses can inherit and implement it againxxxResponse
*/
export interface ApiResponse<T = any> extends BaseResponse {
//wanAndroid-APIresponse body
data: T | any;
//expandxxx-APIresponse body
}
/**
* After encapsulation,Incoming interceptors are not supported
* You need to define your own interface inheritance AxiosRequestConfigtype
* thus supporting incoming interceptors,But the interceptor option should be an optional attribute
* Then request the instance passed inoptionsfor inheritedAxiosRequestConfigcustom type
*/
interface InterceptorHooks {
requestInterceptor?: (config: HttpRequestConfig) => Promise<HttpRequestConfig>;
requestInterceptorCatch?: (error: any) => any;
responseInterceptor?: (response: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>;
responseInterceptorCatch?: (error: any) => any;
}
// @ts-ignore
interface HttpRequestConfig extends InternalAxiosRequestConfig {
showLoading?: boolean; //Whether to display the requestloading
checkResultCode?: boolean; //Whether to check the response result code
checkLoginState?: boolean //Verify user login status
needJumpToLogin?: boolean //Do you need to jump to the login page?
interceptorHooks?: InterceptorHooks;
headers?: AxiosRequestHeaders
}
/**
* Network request structure
* based onaxiosFramework implementation
*/
class AxiosHttpRequest {
config: HttpRequestConfig;
interceptorHooks?: InterceptorHooks;
instance: AxiosInstance;
constructor(options: HttpRequestConfig) {
this.config = options;
this.interceptorHooks = options.interceptorHooks;
this.instance = axios.create(options);
this.setupInterceptor()
}
setupInterceptor(): void {
this.instance.interceptors.request.use(
//Here are mainly high versionsaxiosWhen setting up the interceptor inConfigThe attribute must beInternalAxiosRequestConfig,butInternalAxiosRequestConfiginsideheadersIt is a must pass,So in the implemented subclass, if I set it to be non-required, an error will be reported.,Added an ignore annotation
// @ts-ignore
this.interceptorHooks?.requestInterceptor,
this.interceptorHooks?.requestInterceptorCatch,
);
this.instance.interceptors.response.use(
this.interceptorHooks?.responseInterceptor,
this.interceptorHooks?.responseInterceptorCatch,
);
}
// The role of type parameters,TDecideAxiosResponseIn the exampledatatype
request<T = any>(config: HttpRequestConfig): Promise<T> {
return new Promise<T>((resolve, reject) => {
this.instance
.request<any, T>(config)
.then(res => {
resolve(res);
})
.catch((err) => {
LogUtils.error("network requestRequestabnormal:", err.message)
errorHandler(err)
if (err) {
reject(err);
}
});
});
}
get<T = any>(config: HttpRequestConfig): Promise<T> {
return this.request({ ...config, method: 'GET' });
}
post<T = any>(config: HttpRequestConfig): Promise<T> {
return this.request({ ...config, method: 'POST' });
}
delete<T = any>(config: HttpRequestConfig): Promise<T> {
return this.request({ ...config, method: 'DELETE' });
}
patch<T = any>(config: HttpRequestConfig): Promise<T> {
return this.request({ ...config, method: 'PATCH' });
}
}
export function errorHandler(error: any) {
if (error instanceof AxiosError) {
showToast(error.message)
} else if (error != undefined && error.response != undefined && error.response.status) {
switch (error.response.status) {
// 401: Not logged in
// If you are not logged in, you will be redirected to the login page.,And carry the path of the current page
// Return to the current page after successful login,This step needs to be done on the login page。
case 401:
break;
// 403 tokenExpired
// Prompt user when login expires
// clear localtokenand clearvuexmiddletokenobject
// Jump to login page
case 403:
showToast("Login expired,please login again")
// Cleartoken
// localStorage.removeItem('token');
break;
// 404Request does not exist
case 404:
showToast("The network request does not exist")
break;
// Other errors,Throw an error message directly
default:
showToast(error.response.data.message)
}
}
}
export default AxiosHttpRequest
Client encapsulation
//AxiosRequest.ets
import {AxiosHttpRequest,errorHandler} from './AxiosHttp'
import { AxiosError, AxiosRequestHeaders } from '@ohos/axios';
import { LogUtils } from '../utils/LogUtils';
import showToast from '../utils/ToastUtils';
import { hideLoadingDialog, showLoadingDialog } from '../utils/DialogUtils';
import { StorageUtils } from '../utils/StorageUtils';
import { StorageKeys } from '../constants/StorageKeys';
import { JsonUtils } from '../utils/JsonUtils';
import { Router } from '../route/Router';
import { RoutePath } from '../route/RoutePath';
/**
* axiosRequest client to create
*/
const axiosClient = new AxiosHttpRequest({
baseURL: "/api",
timeout: 10 * 1000,
checkResultCode: false,
headers: {
'Content-Type': 'application/json'
} as AxiosRequestHeaders,
interceptorHooks: {
requestInterceptor: async (config) => {
// Do some processing before sending the request,For example, print request information
LogUtils.debug('network requestRequest Request method:', `{config.method}`);
LogUtils.debug('network requestRequest request link:', `{config.url}`);
LogUtils.debug('network requestRequest Params:', `\n{JsonUtils.stringify(config.params)}`);
LogUtils.debug('network requestRequest Data:', `{JsonUtils.stringify(config.data)}`);
axiosClient.config.showLoading = config.showLoading
if (config.showLoading) {
showLoadingDialog("loading...")
}
if (config.checkLoginState) {
let hasLogin = await StorageUtils.get(StorageKeys.USER_LOGIN, false)
LogUtils.debug('network requestRequest Login status verification>>>', `{hasLogin.toString()}`);
if (hasLogin) {
return config
} else {
if (config.needJumpToLogin) {
Router.push(RoutePath.TestPage)
}
throw new AxiosError("please sign in")
}
}
return config;
},
requestInterceptorCatch: (err) => {
LogUtils.error("network requestRequestError", err.toString())
if (axiosClient.config.showLoading) {
hideLoadingDialog()
}
return err;
},
responseInterceptor: (response) => {
//Prioritize executing your own request response interceptor,Executing a general requestrequestof
if (axiosClient.config.showLoading) {
hideLoadingDialog()
}
LogUtils.debug('Network request responseResponse:', `\n{JsonUtils.stringify(response.data)}`);
if (response.status === 200) {
// @ts-ignore
const checkResultCode = response.config.checkResultCode
if (checkResultCode && response.data.errorCode != 0) {
showToast(response.data.errorMsg)
return Promise.reject(response)
}
return Promise.resolve(response.data);
} else {
return Promise.reject(response);
}
},
responseInterceptorCatch: (error) => {
if (axiosClient.config.showLoading) {
hideLoadingDialog()
}
LogUtils.error("Network request response exception", error.toString())
errorHandler(error);
return Promise.reject(error);
},
}
});
export default axiosClient;
Use after encapsulation
When packaged, use becomes simple. Examples are as follows:
import axiosClient from './AxiosRequest'
let baseUrl = "https://www.wanandroid.com/"
//Return data structure definition
interface HomeModelIssueList {
releaseTime: number;
type: string;
date: number;
publishTime: number;
count: number;
}
interface HomeModel {
issueList: HomeModelIssueList[];
itemList: HomeModelIssueList[];
nextPageUrl: string;
nextPublishTime: number;
newestIssueType: string;
}
interface BannerDataModelData {
desc: string;
id: number;
imagePath: string;
isVisible: number;
order: number;
title: string;
type: number;
url: string;
}
/**
* Request home page data-axiosclient request
* @param date
* @returns
*/
export function getHomeListAxios(date: string = "") {
return axiosClient.get<HomeModel>({
url: baseUrl + "api/v2/feed",
params: { "date": date },
showLoading: true
// headers: { "Accept": "application/json" } as AxiosRequestHeaders
})
}
/**
* Get category details interface
* @param id
* @param start
*/
export function getCategoryDetailList(id: number, start: number) {
return axiosClient.get<HomeModel>(
{
url: baseUrl + "api/v4/categories/videoList",
params: {
"id": id,
"start": start,
"udid": CommonConstants.UUID,
deviceModel: CommonConstants.DEVICE_NUM
}
}
)
}
/**
* ObtainwanAndroidfront pageBannerdata,Test verificationAPI data:TGeneric data
* @returns
*/
export function getWanAndroidBanner() {
return axiosClient.get<ApiResponse<BannerDataModelData[]>>(
{
url: wanAndroidUrl + "/banner/json",
checkResultCode: true,
showLoading: true
}
)
}
Official @ohos/net.http Introduction
In HarmonyOS (OpenHarmony), @ohos/net.http is an officially provided basic module for performing HTTP communication. Developers can use this module to send and receive HTTP requests and responses to implement data interaction between applications and servers.
Document Center –HTTP Data Request
Official Easy Package
The @ohos/net.http module is not easy to use. The simple package is as follows:
//http.ets
/**
* Define interface response wrapper class
*/
import http from '@ohos.net.http';
export interface BaseResponse {
//wanAndroid-APIresponse body
errorCode: number
errorMsg: string
//expandxxx-APIresponse body
}
/**
* Interface implementation class packaging,For example, other businesses can inherit and implement it againxxxResponse
*/
export interface ApiResponse<T = any> extends BaseResponse {
//wanAndroid-APIresponse body
data: T | any;
//expandxxx-APIresponse body
}
interface HttpRequestConfig extends http.HttpRequestOptions {
showLoading?: boolean; //Whether to display the requestloading
checkResultCode?: boolean; //Whether to check the response result code
checkLoginState?: boolean //Verify user login status
needJumpToLogin?: boolean //Do you need to jump to the login page?
url?: string, //Request web link
}
/**
* Network request constructor
* Based on Hongmeng defaulthttpFramework implementation
*/
class HttpBuilder {
httpClient: http.HttpRequest
config: HttpRequestConfig
constructor(options: HttpRequestConfig) {
this.httpClient = http.createHttp()
this.config = options
this.setupInterceptor()
}
/**
* Configure property interceptor
*/
setupInterceptor() {
}
request<T = any>(config: HttpRequestConfig): Promise<T> {
return new Promise<T>((resolve, reject) => {
this.httpClient.request(
config.url,
config,
(error, data) => {
if (!error) {
resolve(data.result as T);
} else {
reject(error)
}
// When the request is finished using,transferdestroyMethod actively destroyedx
this.httpClient.destroy()
}
)
})
}
get<T = any>(config: HttpRequestConfig): Promise<T> {
return this.request({ ...config, method: http.RequestMethod.GET })
}
post<T = any>(config: HttpRequestConfig): Promise<T> {
return this.request({ ...config, method: http.RequestMethod.POST })
}
}
export default HttpBuilder
Official http Module Package Use
import http from '@ohos.net.http';
import showToast from '../utils/ToastUtils';
import HttpBuilder from './http';
//Interface send timeout
const READ_TIMEOUT = 100000
//Interface read timeout
const CONNECT_TIMEOUT = 100000
let baseUrl = "https://www.wanandroid.com/"
const httpClient = new HttpBuilder({
readTimeout: READ_TIMEOUT,
connectTimeout: CONNECT_TIMEOUT
})
//Return data structure definition
interface HomeModelIssueList {
releaseTime: number;
type: string;
date: number;
publishTime: number;
count: number;
}
interface HomeModel {
issueList: HomeModelIssueList[];
itemList: HomeModelIssueList[];
nextPageUrl: string;
nextPublishTime: number;
newestIssueType: string;
}
/**
* Request data--systemhttpask
* @param date
* @returns
*/
export function getHomeList(date: string = "") {
return httpClient.get<HomeModel>({
url: baseUrl + "api/v2/feed",
extraData: { "date": date }
})
}