当前位置:首页>鸿蒙APP>鸿蒙原生网络请求全解(HTTP、HTTPS、文件上传下载、请求拦截、统一封装)

鸿蒙原生网络请求全解(HTTP、HTTPS、文件上传下载、请求拦截、统一封装)

  • 2026-11-02 17:24:43
鸿蒙原生网络请求全解(HTTP、HTTPS、文件上传下载、请求拦截、统一封装)

一、前言

网络请求是App和后端数据交互的核心,几乎所有项目都离不开接口调用、文件上传、资源下载。鸿蒙原生提供fetch与http两种网络方案,很多开发者直接零散写请求代码,上线后频发各类疑难问题:

  • 重复发起接口请求,造成资源浪费、页面数据错乱;

  • 页面销毁未取消请求,引发内存泄漏、无用回调报错;

  • 没有统一请求头、统一异常处理,每个页面重复写冗余代码;

  • 上传下载不会配置参数,大文件上传失败、下载进度无法监听;

  • 缺少请求拦截、响应拦截,token过期不会自动续期跳转登录页。

本篇从原生API实战入手,分步讲解基础请求、文件上传下载,封装商用级统一请求工具类,实现拦截器、loading弹窗、异常统一处理、token自动刷新,代码全量适配API10+,可直接落地商用项目。

二、鸿蒙两种原生请求方案对比

请求方式

底层依赖

优势

适用场景

fetch

W3C标准规范

语法简洁、跨平台通用

普通GET/POST简单接口

@ohos.net.http

鸿蒙原生http模块

功能全面、支持中断、进度监听、精细配置

上传下载、大批量请求、项目统一封装

商用项目优先选择原生http模块封装,扩展性更强,便于统一拦截与管控。

三、前置权限配置

项目使用网络必须在module.json5配置网络权限,否则请求直接报错。

"requestPermissions": [  {    "name": "ohos.permission.INTERNET"  }]

四、原生http基础GET/POST示例

4.1 GET请求

import http from '@ohos.net.http';function getDemo() {  let httpRequest = http.createHttp();  httpRequest.request(    'https://httpbin.org/get',    {      method: http.RequestMethod.GET,      connectTimeout: 10000,      readTimeout: 10000    },    (err, res) => {      if (!err) {        console.info('返回数据:', res.result)      } else {        console.error('请求失败:', err)      }      httpRequest.destroy()    }  )}

4.2 POST表单与JSON请求

import http from '@ohos.net.http';function postJson() {  let httpRequest = http.createHttp();  const params = JSON.stringify({name:"test",age:18})  httpRequest.request('https://httpbin.org/post',{    method: http.RequestMethod.POST,    header: {      'Content-Type':'application/json'    },    extraData: params  },(err,res)=>{    httpRequest.destroy()  })}

重点:请求用完必须调用destroy销毁实例,防止内存堆积。

五、文件上传、下载实战

5.1 文件上传

通过FormData格式携带文件与参数,适配后端multipart/form-data接收。

5.2 文件下载+进度监听

onDataReceive监听分片数据,实时计算下载进度,实现进度条展示;请求可手动中断终止下载。

六、商用全局请求封装(核心)

新建common/HttpUtil.ets,统一封装,实现功能:

  1. 全局统一baseUrl,环境一键切换(测试/生产)

  2. 请求拦截:自动携带token、统一请求头

  3. 响应拦截:统一状态码处理、401自动跳转登录

  4. 全局加载弹窗、统一异常提示

  5. 请求队列管理,页面销毁批量取消请求

import http from '@ohos.net.http';// 全局环境配置const BASE_URL = "https://httpbin.org"let requestList:http.HttpRequest[] = []// 封装请求类export class Http {  // 请求拦截器  private beforeRequest(options:http.HttpRequestOptions){    options.header = {      'token':globalThis.token || "",      'Content-Type':'application/json;charset=utf-8',      ...options.header    }    return options  }  // 响应拦截  private responseFilter(res:http.HttpResponse){    let data = res.result    // 401 登录失效    if(res.responseCode === 401){      // 跳转登录页面逻辑      globalThis.token = ""    }    return data  }  async request(url:string,options:http.HttpRequestOptions){    let req = http.createHttp()    requestList.push(req)    options = this.beforeRequest(options)    try {      let res = await req.request(`${BASE_URL}${url}`,options)      return this.responseFilter(res)    }catch(e){      console.error("请求异常",e)      return Promise.reject(e)    }finally {      let idx = requestList.indexOf(req)      if(idx > -1) requestList.splice(idx,1)      req.destroy()    }  }  get(url:string,params?:Record<string,string>){    let opt:http.HttpRequestOptions = {method:http.RequestMethod.GET}    return this.request(url,opt)  }  post(url:string,data?:Object){    let opt:http.HttpRequestOptions = {      method:http.RequestMethod.POST,      extraData:JSON.stringify(data)    }    return this.request(url,opt)  }  // 页面销毁取消全部排队请求  cancelAll(){    requestList.forEach(item=>{      item.destroy()    })    requestList = []  }}// 全局单例导出export const http = new Http()

七、页面调用示例

import {http} from './common/HttpUtil'@Entry@Componentstruct NetPage {  @State resText:string = ""  aboutToAppear(){    this.loadData()  }  aboutToDisappear(){    // 页面退出取消未完成请求    http.cancelAll()  }  async loadData(){    let res = await http.get('/get')    this.resText = JSON.stringify(res)  }  build(){    Column(){      Text(this.resText).fontSize(14).padding(10)    }.width('100%').height('100%')  }}

八、高频坑点汇总

  • 坑1:http实例不destroy:频繁创建不销毁,APP内存持续上涨,低端机闪退;

  • 坑2:页面销毁未取消请求:页面关闭后回调继续执行,操作已销毁组件引发报错;

  • 坑3:Content-Type配置错误:JSON和表单格式混用,后端接收参数为空;

  • 坑4:无超时时间:弱网环境请求无限挂起,页面卡死;建议统一10s超时;

  • 坑5:硬编码接口地址:环境切换需要全项目改地址,统一BASE_URL管理。

九、项目优化拓展方案

  1. 增加请求防抖:短时间重复相同接口自动拦截;

  2. 增加离线缓存:无网状态读取本地缓存数据;

  3. 封装统一异常弹窗:404/500/超时分类提示文案;

  4. token续期拦截:返回特定状态码自动静默刷新token并重试原请求。

十、全文总结

网络请求是鸿蒙项目工程化的关键一环,零散裸写请求只适合临时测试,商用项目必须统一封装http工具类。借助请求拦截、响应拦截、请求销毁管控,能统一解决80%的接口相关bug、内存泄漏问题。

本文封装的Http工具类开箱即用,后续新增接口只需要调用get/post方法,无需重复处理header、异常、销毁逻辑,大幅提升开发效率。

最新文章

随机文章