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则是有权限了
  }
})

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

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

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

javascript 复制代码
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:string
      success:string
      data:path
    }
    interface resType{
      body:bodyType
    }
    try {
      request.uploadFile(context, uploadConfig).then((data: request.UploadTask) => {
        uploadTask.on('headerReceive', (header:object) => {
          const picRes:resType = header as resType
          console.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对象请求

javascript 复制代码
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 dataType
      const path = data.data.filePath
      console.info("request result" ,path);
    }).catch((error: AxiosError) => {
      console.error("error:" + JSON.stringify(error));
    })

  }

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

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

相关推荐
周胡杰26 分钟前
鸿蒙加载预置数据库-关系型数据库-如何读取本地/预制数据库
数据库·华为·harmonyos·鸿蒙
脑子缺根弦2 小时前
融合优势:SIP 广播对讲联动华为会议 全场景沟通响应提速
华为·音视频·广播对讲系统
迷曳10 小时前
27、鸿蒙Harmony Next开发:ArkTS并发(Promise和async/await和多线程并发TaskPool和Worker的使用)
前端·华为·多线程·harmonyos
呆呆的小鳄鱼14 小时前
牛客:HJ24 合唱队[华为机考][最长递增子集][动态规划]
算法·华为·动态规划
迷曳15 小时前
24、鸿蒙Harmony Next开发:不依赖UI组件的全局自定义弹出框 (openCustomDialog)
dialog·前端·ui·harmonyos·鸿蒙
NoirSeeker15 小时前
在windows平台上基于OpenHarmony sdk编译三方库并暴露给ArkTS使用(详细)
c++·windows·arkts·鸿蒙·交叉编译
DC_BLOG16 小时前
OSPFv3中LSA参数
运维·服务器·华为·智能路由器·huawei
平谷一勺1 天前
鸿蒙状态栏操作
华为·harmonyos·沉浸式状态栏
博睿谷IT99_1 天前
入门华为人工智能,HCIA/HCIP/HCIE该怎么选?
人工智能·华为·华为认证
江湖有缘1 天前
基于华为欧拉系统安装FileGator文件管理器
华为