HarmonyOS 图片上传失败?

/*图片选择
选取单个图片
 */
import { Logger } from '@neu/common';

import { BusinessError } from '@ohos.base';
import picker from '@ohos.file.picker';
import { textAttribute12_300_dark } from './CommonModifier';
import common from '@ohos.app.ability.common';
import httpClient from '../../api/request';

const TAG = ['UploadPhoto']

/*
//http请求config打印
{"method":"POST","readTimeout":90000,"connectTimeout":90000,"url":"./add_refund_attach","multiFormDataList":[{"name":"refundAttach","contentType":"image/jpeg","filePath":"file://media/Photo/3/IMG_1719818021_002/IMG_20240701_151201.jpg"}],"header":{"deviceType":"iPhone","deviceId":"03ca323e-77cb-45ac-9519-f80c8a1464c3","deviceModel":"iPhone4.21.2","sessionId":"34d97ff324a389f6cc5edc98481fd6b9","version":"42102","timeStamp":"1720418411794","deviceKey":"AFF1EC04FF6A61B27EF124747AAF4FD7","content-Type":"multipart/form-data"},"expectDataType":1,"extraData":{"param":"TOZLDlPGCNUai84qeL3QmD0/U8dZ5WJoElY2rwoxVCc="}}

//http请求error报错
{"code":2300026,"message":"Failed to open/read local data from file/application"}



*/
@Component
export struct UploadPhoto {
  select?: (url: string) => void
  @State uri: string = ''

  build() {
    RelativeContainer() {
      Image($r("app.media.add_photo"))
        .width(30)
        .height(30)
        .margin({ top: 13 })
        .id('icon')
        .alignRules({
          middle: { anchor: '__container__', align: HorizontalAlign.Center },
          top: { anchor: '__container__', align: VerticalAlign.Top }
        })
        .visibility(!this.uri ? Visibility.Visible : Visibility.None)
      Text($r('app.string.order_detail_upload'))
        .attributeModifier(textAttribute12_300_dark)
        .id('text')
        .margin({ top: 7 })
        .alignRules({
          middle: { anchor: '__container__', align: HorizontalAlign.Center },
          top: { anchor: 'icon', align: VerticalAlign.Bottom }
        })
        .visibility(!this.uri ? Visibility.Visible : Visibility.None)
      Image(this.uri)
        .id('photo')
        .alignRules({
          left: { anchor: '__container__', align: HorizontalAlign.Start },
          top: { anchor: '__container__', align: VerticalAlign.Top }
        }).visibility(this.uri ? Visibility.Visible : Visibility.None)
      Image($r('app.media.icon_orange_btn_delete'))
        .width(20)
        .height(20)
        .id('close')
        .alignRules({
          middle: { anchor: '__container__', align: HorizontalAlign.End },
          center: { anchor: '__container__', align: VerticalAlign.Top }
        })
        .visibility(this.uri ? Visibility.Visible : Visibility.None)
        .onClick(() => {
          this.uri = ''
          this.select?.(this.uri)
        })
    }
    .width(74)
    .height(73)
    .borderColor('#003D69')
    .borderStyle(BorderStyle.Dotted)
    .borderWidth(this.uri ? 0 : 1)
    .onClick(() => {
      !this.uri && this.getFileAssetsFromType();
    })
    .borderRadius(6)
  }

  // 接口采用promise异步返回形式,传入可选参数DocumentSelectOptions对象,返回选择文件的uri数组。
  async getFileAssetsFromType() {
    const photoSelectOptions = new picker.PhotoSelectOptions(); // 创建图片-音频类型文件-预览的图库选项实例
    // 选择媒体文件类型和选择媒体文件的最大数目
    photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; // 选择媒体文件类型为Image

    photoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
    let context = getContext(this) as common.Context;
    // TODO:知识点:创建图库选择器实例,调用photoViewPicker.select()接口拉起图库界面进行文件选择,文件选择成功后,返回photoSelectResult结果集。
    const photoViewPicker = new picker.PhotoViewPicker(context);
    photoViewPicker.select(photoSelectOptions)
      .then((photoSelectResult: picker.PhotoSelectResult) => {
        const uris = photoSelectResult.photoUris;
        this.uri = uris[0] || ''
        // this.select?.(this.uri)
        httpClient.upload({
          url: '/add_refund_attach',
          multiFormDataList: [{
            name: 'refundAttach',
            contentType: 'image/jpeg',
            filePath: this.uri,
          }]
        });
      }).catch((err: BusinessError) => {
      Logger.info(TAG)
      return;
    })
  }
}
阅读 458
1 个回答

filePath需要转换为沙箱文件路径

//  参考demo:
let uris: Array<string> = [];
const photoViewPicker = new picker.PhotoViewPicker();
const photoSelectOptions = new picker.PhotoSelectOptions();
photoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
photoViewPicker.select(photoSelectOptions).then((photoSelectResult: picker.PhotoSelectResult) => {
  uris = photoSelectResult.photoUris;
  console.info('photoViewPicker.select to file succeed and uris are:' + uris);
  let file = fs.openSync(uris[0], fs.OpenMode.READ_ONLY);

  let file2 = fs.openSync(this.filesDir + '/test.jpg', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  //先创建有读写权限的文件,再把不可读写的文件复制过来
  fs.copyFileSync(file.fd, file2.fd);
  // 关闭文件
  fs.closeSync(file);
  fs.closeSync(file2);

}).catch((err: BusinessError) => {
  console.error('Invoke photoViewPicker.select failed', 'code is:'+ `${err.code}`,' message is:'+ `${err.message}`);
})

请尝试转换path为应用的沙箱路径后再上传图片

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
HarmonyOS
子站问答
访问
宣传栏