网络哀求(http,axios)
一、应用权限管理
应用权限掩护的对象分数据和功能的:
- 数据:个人(照片,通讯录,日历,位置)、装备(标识码,相机,麦克风)
- 功能:装备(摄像头/麦克风、电话、联网)、应用(悬浮窗、快捷方式、唤起第三方应用、背景运行)
1.1权限的品级
system_core: 该品级提供应用服务操纵体系的 - 焦点本领
system_basic:该品级提供应用服务的 - 底子服务
normal: 寻常的根本应用:默认
1.2授权方式
system_grant:体系授权
指的是体系范例的权限,应用被允许访问的数据不会涉及到用户或装备的敏感信息
安装应用是,应用会扣问体系,体系会主动举行授权。
user_grant:用户授权
指的是涉及用户隐私或敏感数据的,假如出现题目,是不可控的。
应用安装后,运行时,会指定弹窗,扣问用户是否允许获取权限。
1.3声明权限的设置
在 entry/src/main/module.json5 设置文件中,声明权限:
- 例:当不需要用户确认和用户确认运行都需要在requestPermissions[]中进行配置:
- 1. 不需要用户确认:
- {
- "name": "ohos.permission.INTERNET" //权限名称:网络
- },
- 2. 用户确认 (当需要用户确认时,填写配置信息会有提示,不填则报错)
- 例:在卡片Call机制中也用到了,保持后台应用:
- 格式:
- {
- "name": "ohos.permission.LOCATION", //定位
- "reason": "$string:reason_loc", //描述申请的原因:user_grant时,必填项,因为需要国际化需要在语言文件中设置才可以
- "usedScene": { //描述权限使用的场景:user_grant时,必填项
- "abilities": [ "EntryAbility" ], //标识需要使用该权限的 Ability
- "when": "always" //标识使用的时机:inuse:只允许前台, always:前后台都允许
- }
复制代码 1.4怎样向用户举行申请
- 例:定位
- import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; //权限控制管理
- onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
- //唤醒用户授权窗口,只有在user_grant情况下有效
- try{
- //创建一个权限管理对象
- const manager = abilityAccessCtrl.createAtManager()
- //基于管理对象,申请用户授权
- manager.requestPermissionsFromUser( this.context, [
- "ohos.permission.LOCATION",
- "ohos.permission.APPROXIMATELY_LOCATION",
- ...
- ] )
- }
- catch(err){
- promptAction.showToast({message:'获取位置失败!'})
- }
- hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
- }
复制代码 1.5 处置惩罚完备流程:(根据实际调解)
当必要访问网络哀求大概开启定位、麦克风、相机等功能时,体系级别直接可以到场权限,用户级别则必要用户授权后才可以举行访问。
当给予用户授权可以会遭遇拒绝,此时则必要举行二次申请授权,此时则必要拉起详细位置举行对app授权
- 解题思路:
- 1.要加入权限
- 2.校验权限是否开发,判断
- 3.没有开启:则申请二次授权,跳转至系统设置位置
- 4.开启:执行正常业务
复制代码 例: 按照定位权限为例
- 1.要加入权限
- {
- "name": 'ohos.permission.APPROXIMATELY_LOCATION',
- "reason": "$string:reason1",
- "usedScene": {
- "abilities": [
- 'EntryAbility'
- ],
- "when": "inuse" // 只在前台
- }
- },
- {
- "name": "ohos.permission.LOCATION",
- "reason": '$string:reason2',
- "usedScene": {
- "abilities": [
- 'EntryAbility'
- ],
- "when": "inuse"
- }
- }
复制代码- 2.校验权限是否开发,判断
- let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
- // 获取tokenId
- let bundleInfo: bundleManager.BundleInfo =
- await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); // 固定参数,可以查看官网
- let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
-
- const permissions: Array<Permissions> = ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'];
-
- const grantStatus = await atManager.checkAccessToken(appInfo.accessTokenId, permissions[0]);
复制代码- 3.没有开启:则申请二次授权,跳转至系统设置位置
- 开启判断 // 其实值为0
- if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
- 未开启判断 // 其实值为-1
- if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED)
- 当没有开启时,二次授权:
- // 若没有权限
- if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
- //1. 获取查看是否已经授权
- //2.拉起设置页面
- 3.1. 获取查看是否已经授权
- let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
- const data = await atManager.requestPermissionsFromUser(getContext(this), permissions)
- let grantStatus: Array<number> = data.authResults;
- // 再次校验是否开启
- if (grantStatus[0] ==abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
- 3.2 拉起设置页面
- const context = getContext(this) as common.UIAbilityContext
- const want: Want = {
- bundleName: "com.huawei.hmos.settings",
- abilityName: "com.huawei.hmos.settings.MainAbility", //设置贞的ability名称
- uri: "application_info_entry",
- parameters: {
- pushParams: appInfo.name //因为要知道是哪个应用需要打开设置
- }
-
- }
- await context.startAbility(want)
- }
- } else{
- // 已经开启了 ,执行正常的业务
- }
复制代码 扩展:哀求方式
GET:
短文本哀求,是一种不安全的哀求,全部的信息都袒露在所在栏中。
内容的上限是255个字节。
通常都是直接打开网址、超链接a它们利用。
POST:
长文本哀求,是一种安全的哀求,基于http超文本传输协议的。
数据信息是通过TCP/IP哀求协议举行处置惩罚的,用户不可见。
数据上限:2MB
现在,我们有一个RestFul哀求风格界说,它扩展了更多的哀求方式:并不是全部后端服务器都支持
- PUT:
- 本质还是post请求。
- DELETE:
- 本质还是get请求。
复制代码 二、内置http哀求利用
大概会存在个版本不兼容题目:发起利用Axios
- 1.开启网络权限: 'ohos.permission.INTERNET'
- 2.导包: import http from '@ohos.net.http'
- 3.请求:
- //创建网络请求对象
- const httpRequest:http.HttpRequest = http.createHttp()
- // 方式一:异步
- //异步方法:data就是响应回发的结果
- //httpRequest.request('url', {...}, (err,data)=>{})
- // 方式二: 同步
- //转同步操作
- try{
- const res:http.HttpResponse = await httpRequest.request(
- 'https://jsonplaceholder.typicode.com/users',
- {method: http.RequestMethod.GET} //get请求方式:默认
- )
- //处理请求结果:得到一个json对象
- console.info('http===', res.responseCode) //状态码
- console.info('http===', JSON.stringify(res.header)) //头部信息
- console.info('http===', JSON.stringify(res.result)) //数据结果
- }
- catch(err){
- console.info('http===', err)
- }
- finally{
- //不管成功还是失败,最终,始终关闭请求对象
- httpRequest.destroy()
- }
复制代码 2.1 工具包
- 使用方式:
- export const tasksList = async (params: TaskModel) => {
- return await Request.get<taskResInfoModel>('/tasks/list', params)
- }
复制代码- //实现原生http|axios的封装
- import { http } from '@kit.NetworkKit'
- import { BASE_URL, TOKEN_KEY } from '../constants'
- import { promptAction } from '@kit.ArkUI'
- import { UserSettingClass } from './setting'
- import { ResponseData } from '../models'
- import { BusinessError } from '@kit.BasicServicesKit'
- /**
- * 调用服务器接口的方法
- * @param url 接口地址 /account/login
- * @param method 请求方式
- * @param data 携带的数据
- * @returns
- */
- export async function requestHttp<T>(
- url: string = "",
- method: http.RequestMethod = http.RequestMethod.GET,
- data?: object): Promise<T> {
- //1.创建请求
- const httpRequest = http.createHttp()
- let urlStr = BASE_URL + url
- //GET方式传递的参数:url?key1=value1&key2=value2
- if (method === http.RequestMethod.GET) {
- if (data && Object.keys(data).length) {
- urlStr += "?" + Object.keys(data).map(key => {
- if (data[key]) {
- return `${key}=${data[key]}`
- }
- return ""
- }).join("&")
- }
- }
- //设置请求头
- const config: http.HttpRequestOptions = {
- method: method, //思考:不同的请求方式,如何携带数据?
- extraData: method === http.RequestMethod.GET ? "" : data, //POST方式传递的数据
- header: {
- "Content-Type": "application/json",
- "Authorization": AppStorage.get(TOKEN_KEY) || ""//获取用户令牌
- }
- }
- try {
- //2.发送请求
- const res = await httpRequest.request(urlStr, config)
- //处理请求结果:得到一个json对象
- // console.info('http===', res.responseCode) //状态码
- // console.info('http===', JSON.stringify(res.header)) //头部信息
- // console.info('http===', JSON.stringify(res.result)) //数据结果
-
- // 3.解析结果
- if (res.responseCode === 401) {
- promptAction.showToast({ message: "未授权或Token超时!" })
- AppStorage.set(TOKEN_KEY, "") //删除token
- new UserSettingClass(getContext()).setUserToken("") //清空首选项
- return Promise.reject(new Error("未授权或Token超时!"))
- } else if (res.responseCode === 404) {
- promptAction.showToast({ message: "请求地址错误!" })
- return Promise.reject(new Error("请求地址错误!"))
- } else {
- const result = JSON.parse(res.result as string) as ResponseData<T>
- if (result.code === 200) {
- //执行成功
- return result.data as T //直接返回数据
- } else {
- promptAction.showToast({ message: result.msg })
- return Promise.reject(new Error(result.msg))
- }
- }
- } catch (error) {
- promptAction.showToast({ message: JSON.stringify(error) })
- return Promise.reject(error.message)
- } finally {
- //4.销毁
- httpRequest.destroy()
- }
- }
- export class Request {
- static get<T>(url: string, data?: object): Promise<T> {
- return requestHttp<T>(url, http.RequestMethod.GET, data)
- }
- static post<T>(url: string, data?: object): Promise<T> {
- return requestHttp<T>(url, http.RequestMethod.POST, data)
- }
- static delete<T>(url: string, data?: object): Promise<T> {
- return requestHttp<T>(url, http.RequestMethod.DELETE, data)
- }
- static put<T>(url: string, data?: object): Promise<T> {
- return requestHttp<T>(url, http.RequestMethod.PUT, data)
- }
- }
复制代码 三、Axios哀求利用(发起)
利用Axios必要安装ohpm中的 axios依赖大概在oh-package.json5 到场依赖
方式一:根据下令安装:ohpm install @ohos/axios
方式二:“@ohos/axios”:“^2.2.0”
3.1 利用方式一
直接调用get(),post(), 不发起利用,缘故起因路径每次都是完备的,有重复性
- 例:
- 开启网络权限: 'ohos.permission.INTERNET'
- 导包: import axios from '@ohos/axios'
- axios.get('完整url',{params:{}})
- axios.post('完整url')
复制代码 3.2 利用方式二(发起)
界说出来公用部分,若不类似可以在调用时举行覆盖
- 使用方式:
- export const tasksList = async (params: TaskModel) => {
- return await Request.get<taskResInfoModel>('/tasks/list', params)
- }
复制代码- 例:
- 开启网络权限: 'ohos.permission.INTERNET'
- 导包: import axios from '@ohos/axios'
- // 1.公共部分
- const cont = axios.create({
- baseURL:'https://atstudy-1253850831.cos.ap-shanghai.myqcloud.com', // 公用部分的url
- //transformRequest:()=>{}, // 发送请求前的操作函数 // 知道别用出错有点难找
- //transformResponse:()=>{}, // 接收结果 // 知道别用出错有点难找
- timeout:3*1000, // 请求超时时间
- headers:{} // 头部数据
- })
- // 格式: 2.调用 cont.get() / cont.post()
- // 此处使用的异步,也可以转为async同步
- cont.get('/lab-d3/harmonyOS/meituan/shop.json',
- {timeout:6*1000} // 重写超时时间
- ).then((res: AxiosResponse) => {
- if (res.status == 200) { // 状态码
- res.data // 返回数据
- }
- })
- .catch((err: BusinessError) => {
- promptAction.showToast({ message: "get请求异常"})
- })
- .finally(() => { })
复制代码 3.3 工具包(发起)
- Axios工具包:
- import axios, { AxiosResponse } from '@ohos/axios'
- import { BASE_URL, USER_TOKEN } from '../constants/setting'
- import { ResponseData } from '../models'
- export class AxiosUtil {
- public static async get<T>(url: string, extraData: string | Object | ArrayBuffer = ''): Promise<T> {
- const arr = Object.keys(extraData)
- let params = arr.map((item: string,index) => {
- if ( (extraData as object)[item]) {
- return arr[index] as string + '=' + (extraData as object)[item]
- // arr[0] key
- // (extraData as object)[item] // 值
- }
- return ''
- }).join('&')
- const response: AxiosResponse = await ReqAxios().get(url + '?' + params)
- const res = response.data as ResponseData<string>
- return res.data as T
- }
- public static async post<T>(url: string, extraData: string | Object | ArrayBuffer = ''): Promise<T> {
- const response: AxiosResponse = await ReqAxios().post(url, extraData)
- const res = response.data as ResponseData<string>
- return res.data as T
- }
- public static async put<T>(url: string, extraData: string | Object | ArrayBuffer = ''): Promise<T> {
- const response: AxiosResponse = await ReqAxios().put(url,extraData)
- const res = response?.data as ResponseData<string>
- return res.data as T
- }
- public static async delete<T>(url: string, extraData: string | Object | ArrayBuffer = ''): Promise<T> {
- const arr = Object.keys(extraData)
- let params = arr.map((item: string,index) => {
- return arr[index] as string + '=' + (extraData as object)[item]
- }).join('&')
- const response: AxiosResponse = await ReqAxios().delete(url + '?' + params)
- const res = response?.data as ResponseData<string>
- return res.data as T
- }
- }
- // 封装公用部分url
- function ReqAxios() {
- return axios.create({
- baseURL: BASE_URL,
- timeout: 3 * 1000, // 请求超时时间
- headers: {
- 'content-type': 'application/json',
- 'Authorization': AppStorage.get(USER_TOKEN) as string || null
- }, // 头部数据
- timeoutErrorMessage: '连接超时'
- })
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |