HarmonyOS---权限和http/Axios网络哀求

[复制链接]
发表于 2026-1-14 10:03:28 | 显示全部楼层 |阅读模式
网络哀求(http,axios)
  


一、应用权限管理

   应用权限掩护的对象分数据和功能的:
  

  • 数据:个人(照片,通讯录,日历,位置)、装备(标识码,相机,麦克风)
  • 功能:装备(摄像头/麦克风、电话、联网)、应用(悬浮窗、快捷方式、唤起第三方应用、背景运行)
  1.1权限的品级

   system_core: 该品级提供应用服务操纵体系的 - 焦点本领
system_basic:该品级提供应用服务的 - 底子服务
normal: 寻常的根本应用:默认
  1.2授权方式

   system_grant:体系授权
指的是体系范例的权限,应用被允许访问的数据不会涉及到用户或装备的敏感信息
安装应用是,应用会扣问体系,体系会主动举行授权。
user_grant:用户授权
指的是涉及用户隐私或敏感数据的,假如出现题目,是不可控的。
应用安装后,运行时,会指定弹窗,扣问用户是否允许获取权限。
  

1.3声明权限的设置

在 entry/src/main/module.json5 设置文件中,声明权限:
  1. 例:当不需要用户确认和用户确认运行都需要在requestPermissions[]中进行配置:
  2. 1. 不需要用户确认:
  3.         {
  4.         "name": "ohos.permission.INTERNET"  //权限名称:网络
  5.       },
  6. 2. 用户确认 (当需要用户确认时,填写配置信息会有提示,不填则报错)
  7. 例:在卡片Call机制中也用到了,保持后台应用:
  8. 格式:
  9.         {
  10.         "name": "ohos.permission.LOCATION", //定位
  11.         "reason": "$string:reason_loc",      //描述申请的原因:user_grant时,必填项,因为需要国际化需要在语言文件中设置才可以
  12.         "usedScene": {                       //描述权限使用的场景:user_grant时,必填项
  13.           "abilities": [ "EntryAbility" ],   //标识需要使用该权限的 Ability
  14.           "when": "always"                   //标识使用的时机:inuse:只允许前台, always:前后台都允许
  15.         }
复制代码
1.4怎样向用户举行申请

  1. 例:定位
  2. import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; //权限控制管理
  3. onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  4.     //唤醒用户授权窗口,只有在user_grant情况下有效
  5.     try{
  6.       //创建一个权限管理对象
  7.       const manager = abilityAccessCtrl.createAtManager()
  8.       //基于管理对象,申请用户授权
  9.       manager.requestPermissionsFromUser( this.context, [
  10.         "ohos.permission.LOCATION",
  11.         "ohos.permission.APPROXIMATELY_LOCATION",
  12.         ...
  13.       ] )
  14.     }
  15.     catch(err){
  16.       promptAction.showToast({message:'获取位置失败!'})
  17.     }
  18.     hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  19.   }
复制代码
1.5 处置惩罚完备流程:(根据实际调解)

   当必要访问网络哀求大概开启定位、麦克风、相机等功能时,体系级别直接可以到场权限,用户级别则必要用户授权后才可以举行访问。
当给予用户授权可以会遭遇拒绝,此时则必要举行二次申请授权,此时则必要拉起详细位置举行对app授权
  1. 解题思路:
  2.         1.要加入权限
  3.         2.校验权限是否开发,判断
  4.         3.没有开启:则申请二次授权,跳转至系统设置位置
  5.         4.开启:执行正常业务
复制代码
例: 按照定位权限为例
  1. 1.要加入权限
  2.         {
  3.         "name": 'ohos.permission.APPROXIMATELY_LOCATION',
  4.         "reason": "$string:reason1",
  5.         "usedScene": {
  6.           "abilities": [
  7.             'EntryAbility'
  8.           ],
  9.           "when": "inuse" // 只在前台
  10.         }
  11.       },
  12.       {
  13.         "name": "ohos.permission.LOCATION",
  14.         "reason": '$string:reason2',
  15.         "usedScene": {
  16.           "abilities": [
  17.             'EntryAbility'
  18.           ],
  19.           "when": "inuse"
  20.         }
  21.       }
复制代码
  1. 2.校验权限是否开发,判断
  2. let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  3. // 获取tokenId
  4.     let bundleInfo: bundleManager.BundleInfo =
  5.     await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); // 固定参数,可以查看官网
  6.     let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
  7.    
  8.     const permissions: Array<Permissions> = ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'];
  9.    
  10.     const grantStatus = await atManager.checkAccessToken(appInfo.accessTokenId, permissions[0]);
复制代码
  1. 3.没有开启:则申请二次授权,跳转至系统设置位置
  2. 开启判断 // 其实值为0
  3. if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
  4. 未开启判断 // 其实值为-1
  5. if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED)
  6. 当没有开启时,二次授权:
  7. // 若没有权限
  8.     if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
  9.         //1. 获取查看是否已经授权
  10.         //2.拉起设置页面
  11. 3.1. 获取查看是否已经授权
  12.           let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  13.       const data = await atManager.requestPermissionsFromUser(getContext(this), permissions)
  14.       let grantStatus: Array<number> = data.authResults;
  15.         // 再次校验是否开启
  16.                 if (grantStatus[0] ==abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
  17. 3.2 拉起设置页面
  18.                 const context = getContext(this) as common.UIAbilityContext
  19.                 const want: Want = {
  20.                   bundleName: "com.huawei.hmos.settings",
  21.                   abilityName: "com.huawei.hmos.settings.MainAbility", //设置贞的ability名称
  22.                   uri: "application_info_entry",
  23.                   parameters: {
  24.                     pushParams: appInfo.name //因为要知道是哪个应用需要打开设置
  25.                   }
  26.        
  27.                 }
  28.                 await context.startAbility(want)
  29.         }
  30. } else{
  31.         // 已经开启了 ,执行正常的业务
  32. }
复制代码
  扩展:哀求方式
GET:
短文本哀求,是一种不安全的哀求,全部的信息都袒露在所在栏中。
内容的上限是255个字节。
通常都是直接打开网址、超链接a它们利用。
POST:
长文本哀求,是一种安全的哀求,基于http超文本传输协议的。
数据信息是通过TCP/IP哀求协议举行处置惩罚的,用户不可见。
数据上限:2MB
现在,我们有一个RestFul哀求风格界说,它扩展了更多的哀求方式:并不是全部后端服务器都支持
  1. PUT:
  2.     本质还是post请求。
  3. DELETE:
  4.     本质还是get请求。
复制代码
二、内置http哀求利用

   大概会存在个版本不兼容题目:发起利用Axios
  

  1. 1.开启网络权限: 'ohos.permission.INTERNET'
  2. 2.导包: import http from '@ohos.net.http'
  3. 3.请求:
  4.                 //创建网络请求对象
  5.         const httpRequest:http.HttpRequest = http.createHttp()
  6.                 // 方式一:异步
  7.         //异步方法:data就是响应回发的结果
  8.         //httpRequest.request('url', {...}, (err,data)=>{})
  9.                 // 方式二: 同步
  10.         //转同步操作
  11.         try{
  12.           const res:http.HttpResponse = await httpRequest.request(
  13.             'https://jsonplaceholder.typicode.com/users',
  14.             {method: http.RequestMethod.GET}   //get请求方式:默认
  15.           )
  16.           //处理请求结果:得到一个json对象
  17.           console.info('http===', res.responseCode)           //状态码
  18.           console.info('http===', JSON.stringify(res.header)) //头部信息
  19.           console.info('http===', JSON.stringify(res.result)) //数据结果
  20.         }
  21.         catch(err){
  22.           console.info('http===', err)
  23.         }
  24.         finally{
  25.           //不管成功还是失败,最终,始终关闭请求对象
  26.           httpRequest.destroy()
  27.         }
复制代码
2.1 工具包

  1. 使用方式:
  2. export const tasksList = async (params: TaskModel) => {
  3.   return await Request.get<taskResInfoModel>('/tasks/list', params)
  4. }
复制代码
  1. //实现原生http|axios的封装
  2. import { http } from '@kit.NetworkKit'
  3. import { BASE_URL, TOKEN_KEY } from '../constants'
  4. import { promptAction } from '@kit.ArkUI'
  5. import { UserSettingClass } from './setting'
  6. import { ResponseData } from '../models'
  7. import { BusinessError } from '@kit.BasicServicesKit'
  8. /**
  9. * 调用服务器接口的方法
  10. * @param url 接口地址 /account/login
  11. * @param method 请求方式
  12. * @param data 携带的数据
  13. * @returns
  14. */
  15. export async function requestHttp<T>(
  16.   url: string = "",
  17.   method: http.RequestMethod = http.RequestMethod.GET,
  18.   data?: object): Promise<T> {
  19.   //1.创建请求
  20.   const httpRequest = http.createHttp()
  21.   let urlStr = BASE_URL + url
  22.   //GET方式传递的参数:url?key1=value1&key2=value2
  23.   if (method === http.RequestMethod.GET) {
  24.     if (data && Object.keys(data).length) {
  25.       urlStr += "?" + Object.keys(data).map(key => {
  26.         if (data[key]) {
  27.           return `${key}=${data[key]}`
  28.         }
  29.         return ""
  30.       }).join("&")
  31.     }
  32.   }
  33.   //设置请求头
  34.   const config: http.HttpRequestOptions = {
  35.     method: method, //思考:不同的请求方式,如何携带数据?
  36.     extraData: method === http.RequestMethod.GET ? "" : data, //POST方式传递的数据
  37.     header: {
  38.       "Content-Type": "application/json",
  39.       "Authorization": AppStorage.get(TOKEN_KEY) || ""//获取用户令牌
  40.     }
  41.   }
  42.   try {
  43.     //2.发送请求
  44.     const res = await httpRequest.request(urlStr, config)
  45.         //处理请求结果:得到一个json对象
  46.     // console.info('http===', res.responseCode)           //状态码
  47.     // console.info('http===', JSON.stringify(res.header)) //头部信息
  48.     // console.info('http===', JSON.stringify(res.result)) //数据结果
  49.    
  50.     // 3.解析结果
  51.     if (res.responseCode === 401) {
  52.       promptAction.showToast({ message: "未授权或Token超时!" })
  53.       AppStorage.set(TOKEN_KEY, "") //删除token
  54.       new UserSettingClass(getContext()).setUserToken("") //清空首选项
  55.       return Promise.reject(new Error("未授权或Token超时!"))
  56.     } else if (res.responseCode === 404) {
  57.       promptAction.showToast({ message: "请求地址错误!" })
  58.       return Promise.reject(new Error("请求地址错误!"))
  59.     } else {
  60.       const result = JSON.parse(res.result as string) as ResponseData<T>
  61.       if (result.code === 200) {
  62.         //执行成功
  63.         return result.data as T //直接返回数据
  64.       } else {
  65.         promptAction.showToast({ message: result.msg })
  66.         return Promise.reject(new Error(result.msg))
  67.       }
  68.     }
  69.   } catch (error) {
  70.     promptAction.showToast({ message: JSON.stringify(error) })
  71.     return Promise.reject(error.message)
  72.   } finally {
  73.     //4.销毁
  74.     httpRequest.destroy()
  75.   }
  76. }
  77. export class Request {
  78.   static get<T>(url: string, data?: object): Promise<T> {
  79.     return requestHttp<T>(url, http.RequestMethod.GET, data)
  80.   }
  81.   static post<T>(url: string, data?: object): Promise<T> {
  82.     return requestHttp<T>(url, http.RequestMethod.POST, data)
  83.   }
  84.   static delete<T>(url: string, data?: object): Promise<T> {
  85.     return requestHttp<T>(url, http.RequestMethod.DELETE, data)
  86.   }
  87.   static put<T>(url: string, data?: object): Promise<T> {
  88.     return requestHttp<T>(url, http.RequestMethod.PUT, data)
  89.   }
  90. }
复制代码
三、Axios哀求利用(发起)

   利用Axios必要安装ohpm中的 axios依赖大概在oh-package.json5 到场依赖
方式一:根据下令安装:ohpm install @ohos/axios
方式二:“@ohos/axios”:“^2.2.0”
  3.1 利用方式一

   直接调用get(),post(), 不发起利用,缘故起因路径每次都是完备的,有重复性
  1. 例:
  2. 开启网络权限: 'ohos.permission.INTERNET'
  3. 导包: import axios  from '@ohos/axios'
  4. axios.get('完整url',{params:{}})
  5. axios.post('完整url')
复制代码
3.2 利用方式二(发起)

   界说出来公用部分,若不类似可以在调用时举行覆盖
  1. 使用方式:
  2. export const tasksList = async (params: TaskModel) => {
  3.   return await Request.get<taskResInfoModel>('/tasks/list', params)
  4. }
复制代码
  1. 例:
  2. 开启网络权限: 'ohos.permission.INTERNET'
  3. 导包: import axios  from '@ohos/axios'
  4. // 1.公共部分
  5. const cont =  axios.create({
  6.     baseURL:'https://atstudy-1253850831.cos.ap-shanghai.myqcloud.com', // 公用部分的url
  7.     //transformRequest:()=>{}, // 发送请求前的操作函数 // 知道别用出错有点难找
  8.     //transformResponse:()=>{}, // 接收结果  // 知道别用出错有点难找
  9.     timeout:3*1000, // 请求超时时间
  10.     headers:{} // 头部数据
  11.   })
  12.   // 格式: 2.调用 cont.get() /  cont.post()
  13.   // 此处使用的异步,也可以转为async同步
  14.   cont.get('/lab-d3/harmonyOS/meituan/shop.json',
  15.                  {timeout:6*1000} // 重写超时时间
  16.                  ).then((res: AxiosResponse) => {
  17.                if (res.status == 200) { // 状态码
  18.                  res.data // 返回数据
  19.                }
  20.              })
  21.                .catch((err: BusinessError) => {
  22.                  promptAction.showToast({ message: "get请求异常"})
  23.                })
  24.                .finally(() => {  })
复制代码
3.3 工具包(发起)

  1. Axios工具包:
  2. import axios, { AxiosResponse } from '@ohos/axios'
  3. import { BASE_URL, USER_TOKEN } from '../constants/setting'
  4. import { ResponseData } from '../models'
  5. export class AxiosUtil {
  6.   public static async get<T>(url: string, extraData: string | Object | ArrayBuffer = ''): Promise<T> {
  7.     const arr = Object.keys(extraData)
  8.     let params = arr.map((item: string,index) => {
  9.     if ( (extraData as object)[item]) {
  10.         return arr[index] as string + '=' + (extraData as object)[item]
  11.         // arr[0] key
  12.         // (extraData as object)[item] // 值
  13.       }
  14.       return ''
  15.     }).join('&')
  16.     const response: AxiosResponse = await ReqAxios().get(url + '?' + params)
  17.     const res = response.data as ResponseData<string>
  18.     return res.data as T
  19.   }
  20.   public static async post<T>(url: string, extraData: string | Object | ArrayBuffer = ''): Promise<T> {
  21.     const response: AxiosResponse = await ReqAxios().post(url, extraData)
  22.     const res = response.data as ResponseData<string>
  23.     return res.data as T
  24.   }
  25.   public static async put<T>(url: string, extraData: string | Object | ArrayBuffer = ''): Promise<T> {
  26.     const response: AxiosResponse = await ReqAxios().put(url,extraData)
  27.     const res = response?.data as ResponseData<string>
  28.     return res.data as T
  29.   }
  30.   public static async delete<T>(url: string, extraData: string | Object | ArrayBuffer = ''): Promise<T> {
  31.     const arr = Object.keys(extraData)
  32.     let params = arr.map((item: string,index) => {
  33.       return arr[index] as string + '=' + (extraData as object)[item]
  34.     }).join('&')
  35.     const response: AxiosResponse = await ReqAxios().delete(url + '?' + params)
  36.     const res = response?.data as ResponseData<string>
  37.     return res.data as T
  38.   }
  39. }
  40. // 封装公用部分url
  41. function ReqAxios() {
  42.   return axios.create({
  43.     baseURL: BASE_URL,
  44.     timeout: 3 * 1000, // 请求超时时间
  45.     headers: {
  46.       'content-type': 'application/json',
  47.       'Authorization': AppStorage.get(USER_TOKEN) as string || null
  48.     }, // 头部数据
  49.     timeoutErrorMessage: '连接超时'
  50.   })
  51. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表