鸿蒙应用开发网络请求专题篇

鸿蒙 ArkUI 网络请求(前置下载 + 导航守卫)开发文档

 

一、前置依赖下载与配置

 

1. 网络请求库选择

 
鸿蒙推荐使用官方@ohos.net.http模块,无需额外下载第三方库,直接引入即可;若需简化操作,可下载社区封装的axios-harmony:
 
ets
 
 
// 终端执行下载(ohpm包管理器)
ohpm install axios-harmony
 
 

2. 网络权限配置

 
在module.json5中添加网络访问权限,必须配置否则请求失败:
 
json
 
 
"requestPermissions": [
  { "name": "ohos.permission.INTERNET" },
  { "name": "ohos.permission.GET_NETWORK_INFO" }
]
 
 

3. 环境配置(开发 / 生产)

 
在resources/base/profile/main_pages.json同级创建env.ets:
 
ets
 
 
export const ENV = {
  dev: { BASE_URL: 'https://dev-api.example.com' },
  prod: { BASE_URL: 'https://api.example.com' }
}
export const BASE_URL = ENV.prod.BASE_URL; // 开发时切换为dev
 
 

二、导航守卫实现(页面路由拦截)

 
基于router模块实现全局前置守卫,拦截未登录请求:
 

1. 初始化路由守卫

 
在EntryAbility.ets的onWindowStageCreate中注册:
 
ets
 
 
import router from '@ohos.router';
import { getToken } from './utils/storage'; // 自定义本地存储工具

// 全局导航守卫
router.beforeEach((to, from, next) => {
  const token = getToken();
  // 需登录的页面路径白名单
  const authPages = ['/pages/User', '/pages/Order'];
  if (authPages.includes(to.url) && !token) {
    next('/pages/Login'); // 无token跳转登录
  } else {
    next(); // 放行
  }
});
 
 

2. 本地存储 token 工具(utils/storage.ets)

 
ets
 
 
import preferences from '@ohos.data.preferences';
let pref: preferences.Preferences;

export async function initPref() {
  pref = await preferences.getPreferences(getContext(), 'user_info');
}
export async function setToken(token: string) {
  await pref.put('token', token);
  await pref.flush();
}
export async function getToken(): Promise<string> {
  return await pref.get('token', '') as string;
}
 
 

三、网络请求完整封装(基于官方 http 模块)

 

1. 创建请求实例(utils/request.ets)

 
ets
 
 
import http from '@ohos.net.http';
import { BASE_URL } from '../env';
import { getToken } from './storage';

// 创建http请求实例
const httpRequest = http.createHttp();

// 基础请求函数
export async function request(options: {
  url: string,
  method: http.RequestMethod,
  data?: Object,
  headers?: Object
}) {
  // 拼接完整请求地址
  const fullUrl = `${BASE_URL}${options.url}`;
  // 获取token并设置请求头
  const token = await getToken();
  const headers = {
    'Content-Type': 'application/json',
    'Authorization': token ? `Bearer ${token}` : '',
    ...options.headers
  };

  return new Promise((resolve, reject) => {
    httpRequest.request(
      fullUrl,
      {
        method: options.method,
        header: headers,
        extraData: options.data
      },
      (err, data) => {
        if (!err) {
          // 请求成功处理(状态码200-299)
          if (data.responseCode >= 200 && data.responseCode < 300) {
            resolve(data.result);
          } else {
            // 业务错误(如401未授权)
            if (data.responseCode === 401) {
              router.pushUrl({ url: '/pages/Login' }); // token失效跳转登录
            }
            reject(data.result);
          }
        } else {
          // 网络错误
          reject({ message: '网络请求失败,请检查网络' });
        }
      }
    );
  });
}

// 封装GET/POST方法
export const get = (url: string, params?: Object) => {
  // GET参数拼接
  const query = params ? '?' + new URLSearchParams(params).toString() : '';
  return request({ url: url + query, method: http.RequestMethod.GET });
};
export const post = (url: string, data?: Object) => {
  return request({ url, method: http.RequestMethod.POST, data });
};
 
 

四、页面中使用网络请求

 

1. 登录页面请求(pages/Login.ets)

 
ets
 
 
import { post } from '../utils/request';
import { setToken } from '../utils/storage';
import router from '@ohos.router';

@Entry
@Component
struct Login {
  @State phone: string = '';
  @State password: string = '';

  async handleLogin() {
    try {
      const res: any = await post('/api/login', {
        phone: this.phone,
        password: this.password
      });
      // 存储token并跳转首页
      await setToken(res.data.token);
      router.replaceUrl({ url: '/pages/Home' });
    } catch (err: any) {
      console.error('登录失败:', err.message);
    }
  }

  build() {
    Column() {
      TextInput({ placeholder: '请输入手机号' }).onChange(val => this.phone = val)
      TextInput({ placeholder: '请输入密码' }).type(InputType.Password).onChange(val => this.password = val)
      Button('登录').onClick(() => this.handleLogin())
    }
    .width('100%')
    .padding(16)
  }
}
 
 

2. 首页数据请求(pages/Home.ets)

 
ets
 
 
import { get } from '../utils/request';

@Entry
@Component
struct Home {
  @State bannerList: any[] = [];

  async aboutToAppear() {
    // 页面加载时请求轮播图数据
    try {
      const res: any = await get('/api/banner');
      this.bannerList = res.data;
    } catch (err) {
      console.error('轮播图请求失败:', err);
    }
  }

  build() {
    List() {
      ForEach(this.bannerList, (item) => {
        ListItem() {
          Image(item.imgUrl).width('100%').height(200)
        }
      })
    }
  }
}
 
 

五、关键注意事项

 
  1. 真机调试需开启 “允许调试”,且网络环境需能访问接口地址
  2. 本地开发若用 HTTP 协议,需在module.json5中添加网络安全配置:
 
json
 
 
"networkSecurityConfig": {
  "cleartextTraffic": true
}
 
 
  1. 导航守卫仅对router.pushUrl/replaceUrl生效,页面返回(back)不触发拦截
posted @ 2026-08-02 18:29  鬼门元歌  阅读(23)  评论(0)    收藏  举报