当前位置: 首页 > news >正文

openharmony上传图片,并获取返回路径

适用条件:

openharmony开发

4.0 release版本,对应能力API10

一直不断尝试,一会用官方提供的上传文件,一会用第三方库的axios都不行,

一会报错‘没权限,一会报错’路径错误,还有报错‘401参数错误的,反正各种报错都遇到了,官方文档说的不够仔细,示例也不够清楚,痛苦

首先一定要动态获取权限,很重要 (即使在modules.json5文件里面已经说明了,在页面上还是要判断一下有咩有,然后申请权限)

写在onPageShow里,我没有加是否存在权限的判断,需要自行判断,有权限就不弹了,没权限在向用户申请,弹弹窗

import abilityAccessCtrl, { Context, PermissionRequestResult } from '@ohos.abilityAccessCtrl';
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
let context: Context = getContext(this) as common.UIAbilityContext;
await atManager.requestPermissionsFromUser(context, ["ohos.permission.WRITE_MEDIA","ohos.permission.READ_MEDIA",
], (err: BusinessError, data: PermissionRequestResult) => {if (err) {console.log(`requestPermissionsFromUser fail, err->${JSON.stringify(err)}`);} else {console.info('这是data:' + JSON.stringify(data));console.info('data permissions:' + data.permissions);console.info('data authResults:' + data.authResults); //如果是0则是有权限了}
})

看到这个弹窗,才算权限申请生效了

其次,一定要进行文件的复制,这样才能获取到文件(在下面代码)

方法一,使用官方提供的上传文件请求

import fs from '@ohos.file.fs';
import request from '@ohos.request';//fileUri是文件选择器返回的路径,格式如下: "datashare:///media/image/45"async uploadImg(fileUri: string) {/ 获取应用文件路径const context = getContext(this) as common.UIAbilityContext;let cacheDir = context.cacheDir;  console.log('cacheDir', cacheDir); //=>沙箱路径 /应用文件目录 /data/storage/el2/base/haps/entry/cache//文件名称,下面这两种方法都可以,原则就是保持名字随机性// let segments = fileUri.split('/')// let fileName = segments[segments.length-1]const fileName = Date.now() + '.jpg'//复制这一步一定不能少 ,简而言之,就是把我们的内部文件拿到外部暴露出来,let realUri = context.cacheDir + "/" + fileName //计划复制到的目标路径try {let file =  fs.openSync(fileUri);fs.copyFileSync(file.fd, realUri)} catch (err) {console.info('err:' + JSON.stringify(err));}// // 鸿蒙自带请求let uploadTask: request.UploadTask;let uploadConfig: request.UploadConfig = {url: 'http://upload', //需要手动替换为真实服务器地址header: { 'Content-Type': 'multipart/form-data', token: AppStorage.get('token') },method: "POST",files: [{ filename: fileName, name: "image", uri: `internal://cache/${fileName}`, type: "jpg" }],
//注意这里,files里面的url一定是'internal://cache/'和文件名的拼接,不要拼其他路径!!!data: [],};//一定要定义类型,这里的类型定义真的很让人头大interface path{filePath:string}interface  bodyType{      code:stringsuccess:stringdata:path}interface resType{body:bodyType}try {request.uploadFile(context, uploadConfig).then((data: request.UploadTask) => {uploadTask.on('headerReceive', (header:object) => {const picRes:resType = header as resTypeconsole.log('上传头picRes', picRes.body )})uploadTask.on("complete", () => {promptAction.showToast({ message: '上传成功!', duration: 2000 })// 上传成功调接口})}).catch((err: BusinessError) => {console.error(`Failed to request the upload. Code: ${err.code}, message: ${err.message}`);});} catch (err) {console.error(`Failed to request the upload. err: ${JSON.stringify(err)}`);}}

方法二,使用第三方库 @ohos/axios,创建formdata对象请求

import fs from '@ohos.file.fs';
import axios, { AxiosError, AxiosProgressEvent, AxiosResponse, FormData, InternalAxiosRequestConfig } from '@ohos/axios'//fileUri是文件选择器返回的路径,格式如下: "datashare:///media/image/45"async uploadImg(fileUri: string) {/ 获取应用文件路径const context = getContext(this) as common.UIAbilityContext;let cacheDir = context.cacheDir;  console.log('cacheDir', cacheDir); //=>沙箱路径 /应用文件目录 /data/storage/el2/base/haps/entry/cache//文件名称,下面这两种方法都可以,原则就是保持名字随机性// let segments = fileUri.split('/')// let fileName = segments[segments.length-1]const fileName = Date.now() + '.jpg'//复制这一步一定不能少 ,简而言之,就是把我们的内部文件拿到外部暴露出来,let realUri = context.cacheDir + "/" + fileName //计划复制到的目标路径try {let file =  fs.openSync(fileUri);fs.copyFileSync(file.fd, realUri)} catch (err) {console.info('err:' + JSON.stringify(err));}// 第三方库axios请求let formData = new FormData();formData.append('image', `internal://cache/${fileName}`);// formData.append('image',  'internal://cache/'+fileName);//记得替换真实请求地址axios.post<string, AxiosResponse<string>, FormData>('http://upload', formData, {headers: {'Content-Type': 'multipart/form-data','token': AppStorage.get('token')},context: getContext(this),onUploadProgress: (progressEvent: AxiosProgressEvent): void => {console.info(progressEvent && progressEvent.loaded && progressEvent.total ? Math.ceil(progressEvent.loaded / progressEvent.total * 100) + '%' : '0%');},}).then((res: AxiosResponse) => {interface  pathType{filePath:string}interface dataType{data:pathType}const data: dataType = res.data as dataTypeconst path = data.data.filePathconsole.info("request result" ,path);}).catch((error: AxiosError) => {console.error("error:" + JSON.stringify(error));})}

别夸我,我真是个菩萨,经历了九九八十一难,搞了两天才弄好的上传方法

如果描述哪里不正确,不完整,及时告知我噢

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Unable to obtain driver using Selenium Manager: Selenium Manager failed解决方案
  • 角点检测及MATLAB实现
  • AIGC笔记--基于Stable Diffusion实现图片的inpainting
  • 9.5 栅格图层符号化多波段彩色渲染
  • 网页数据抓取:融合BeautifulSoup和Scrapy的高级爬虫技术
  • Node学习-第六章-express中间件与RESful API接口规范(下)
  • live555 rtsp服务器实战之createNewStreamSource
  • 目标检测--X-anylabeling使用自己的模型自动标注
  • [C++]多态
  • C语言课程回顾:十、C语言之 指针
  • 推荐一款uniapp拖动验证码插件
  • 从LeetCode215看排序算法
  • Nginx集群部署指南:实现高性能和高可用性
  • qt 创建一个可以拖拽的矩形,简单实践
  • 网站架构核心要素
  • 【刷算法】求1+2+3+...+n
  • AngularJS指令开发(1)——参数详解
  • canvas 高仿 Apple Watch 表盘
  • codis proxy处理流程
  • C学习-枚举(九)
  • ES6 ...操作符
  • Git同步原始仓库到Fork仓库中
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • php ci框架整合银盛支付
  • socket.io+express实现聊天室的思考(三)
  • storm drpc实例
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 免费小说阅读小程序
  • 思否第一天
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • # 达梦数据库知识点
  • (13)DroneCAN 适配器节点(一)
  • (2)nginx 安装、启停
  • (31)对象的克隆
  • (C++17) optional的使用
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (二)hibernate配置管理
  • (二)换源+apt-get基础配置+搜狗拼音
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (七)Knockout 创建自定义绑定
  • (四)activit5.23.0修复跟踪高亮显示BUG
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)负载均衡,回话保持,cookie
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (转载)OpenStack Hacker养成指南
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .Net - 类的介绍
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET NPOI导出Excel详解