HarmonyOS鸿蒙Next中axios如何上传文件+其他参数

HarmonyOS鸿蒙Next中axios如何上传文件+其他参数 有俩个参数 1个是file 1个是字符串

let formData = new FormData()
// formData.append('file', mubanUrl)
let uri =FileUtil.getUriFromPath(fileReceive)
formData.append('onePortraitFile',uri)

console.log("zqf mubanUrl ",mubanUrl)
console.log("zqf onePortraitFile ",uri)

axios.post<string, AxiosResponse<string>, FormData>(HttpConst.AI_XIEZHEN, formData, {
  headers: getYaKunHeader(),
  context: getContext(this),
  params:{
    file:mubanUrl
  }
}).then((res: AxiosResponse) => {
  console.info("zqf result" + JSON.stringify(res.data));
}).catch((error: AxiosError) => {
  console.error("zqf error:" + JSON.stringify(error));
})

大佬们 这种写法对吗~一直请求错误…


更多关于HarmonyOS鸿蒙Next中axios如何上传文件+其他参数的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

开发者你好,给您提供一个axios批量上传文件的方法参考一下:

// 将待上传文件预置于resources目录下的resfile目录,应用安装后,resfile资源会被解压到应用沙箱路径
async uploadFile(context: Context, url: string, resFilenames: string[]): Promise<Result> {
  let result: Result = {}
  if (!resFilenames || resFilenames.length < 1) {
    return result
  }
  // axios表单数据
  let formData = new FormData()
  // 表单添加非文件类型参数
  formData.append('type', 258)

  // 通过Context属性resourceDir获取到resfile资源目录后,可通过文件路径访问,且该路径仅能以只读方式访问。

  let resourceDir = context.resourceDir
  // 获取缓存目录
  const cacheDir = context.cacheDir
  for (let resFilename of resFilenames) {
    let resFilePath = resourceDir + '/' + resFilename
    let cacheFilePath = cacheDir + '/' + resFilename
    try {
      // 将resfile资源文件拷贝至缓存目录中
      const oldFile = fileIo.openSync(resFilePath, fileIo.OpenMode.READ_ONLY)
      fileIo.copyFileSync(oldFile.fd, cacheFilePath)

      let file = fs.openSync(cacheFilePath, fs.OpenMode.READ_WRITE);
      let stat = fs.lstatSync(cacheFilePath);
      let buf = new ArrayBuffer(stat.size);
      // 以同步方法从流文件读取数据。
      fs.readSync(file.fd, buf);
      fs.fsyncSync(file.fd);
      fs.closeSync(file.fd);

      // 将文件流添加至表单数据中
      formData.append('files', buf, { filename: resFilename, type: 'image/png' });
    } catch (err) {
      hilog.error(0x0000, 'testTag', 'uploadFile copyFileSync fail %{public}s', JSON.stringify(err) ?? '');
    }
  }

  try {
    let res: AxiosResponse = await axios.post<string, AxiosResponse<string>, FormData>(url, formData,
      {
        // 指定请求头中ContentType未表单类型
        headers: { 'Content-Type': 'multipart/form-data' },
        onUploadProgress: (progressEvent: AxiosProgressEvent): void => {
          console.info('uploadFile onUploadProgress: ' +
            progressEvent && progressEvent.loaded && progressEvent.total ?
            Math.ceil(progressEvent.loaded / progressEvent.total * 100) + '%' : '0%');
        },
      })
    result.statue = res ? JSON.stringify(res.status) : '';
    result.data = res ? JSON.stringify(res.data) : '';
    result.statusText = res ? res.statusText : '';
  } catch (err) {
    console.error("uploadFile error: " + err.code + ":" + err.message);
  }
  return result
}

服务端使用MultipartFile[]接受多个文件,表单参数名称需要一一对应。

@PostMapping("/batchUploadFile")
public String batchUploadFile(
  @RequestParam(name = "type", required = false) Integer type,
  @RequestPart(name = "files", required = false) MultipartFile[] files) {
    // 服务端业务逻辑
}

若是不能解决您的问题,请提供以下信息: (信息根据实际情况选择)

1.问题现象(如:报错日志(获取方式:xxx)、异常截图、问题背景);

2.复现代码(如最小复现demo),是否可以提供完整的上传代码;

3.版本信息(如:开发工具、手机系统版本信息、以及axios三方库的版本);

更多关于HarmonyOS鸿蒙Next中axios如何上传文件+其他参数的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


背景知识:

上传一个问题需要用到获取文件路径,构造给 FormData 对象给到 axios。然后调用post就可以上传了。

问题解决:

示例代码:

// 1、获取到一个图片的路径
const fileName = util.generateRandomUUID() + ".jpg";
const targetPath = getContext().cacheDir + '/' + fileName;
fileIo.copyFileSync(sourceFile.fd, targetFile.fd);

//2、构造一个 FormData对象,将路径放入参数中,在附加其他的参数
const formData = new FormData();
formData.append("img", `internal://cache/${fileName}`); // 沙箱文件路径
formData.append("fileSize", "1024");                   // 附加参数

// 3、调用post方法传入参数,就可以进行上传了。
axios.post('https://your-api.com/upload', formData, {
  headers: { 'Content-Type': 'multipart/form-data' },
  context: getContext(this) // 确保访问沙箱权限
}).then((res) => {
  // 处理响应
}).catch((error) => {
  // 错误处理
});

FormData介绍

FormData对象是axios内部自定义的类型,用以将数据编译成键值对,以便用来发送数据。其主要用于发送表单数据,但亦可用于发送带键数据 (keyed data)。

import { FormData } from '@ohos/axios'

let formData: FormData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", "123456");
formData.append("accountnum", "123456");
formData.append("file", "internal://cache/xx/file.txt", { filename: "text.txt", type: "text/plain"}); 

上面的示例创建了一个 FormData 实例,包含"username"、"accountnum"字段。使用 append() 方法时,可以通过第三个可选参数设置多部分表单数据的数据名称和数据类型。

在HarmonyOS Next中,使用axios上传文件及参数需通过FormData实现。首先创建FormData对象,使用append方法添加文件和其他参数。文件参数以Blob或File类型添加,其他参数以键值对形式添加。然后配置axios请求,设置请求头Content-Type为multipart/form-data,并将FormData作为请求体发送POST请求。示例代码:

import axios from 'axios';
let formData = new FormData();
formData.append('file', fileBlob);
formData.append('key', 'value');
axios.post('url', formData, {
  headers: { 'Content-Type': 'multipart/form-data' }
});

确保文件路径或对象正确,服务器端相应支持multipart/form-data格式。

你的代码存在两个主要问题:

  1. 参数传递方式错误:文件应该通过FormData的body传递,字符串参数应该放在URL的query参数中。你目前把文件同时放在了FormData和params里,这是重复的。

  2. 文件URI处理问题:在HarmonyOS Next中,直接使用FileUtil.getUriFromPath获取的URI可能无法被axios正确识别为文件对象。

建议修改为:

let formData = new FormData();
// 只将文件添加到FormData
let uri = FileUtil.getUriFromPath(fileReceive);
formData.append('onePortraitFile', {
  uri: uri,
  type: 'multipart/form-data',
  name: 'filename.jpg' // 根据实际文件类型设置
});

axios.post<string, AxiosResponse<string>, FormData>(
  HttpConst.AI_XIEZHEN, 
  formData, 
  {
    headers: getYaKunHeader(),
    context: getContext(this),
    params: {
      file: mubanUrl // 字符串参数放在params中
    }
  }
).then((res: AxiosResponse) => {
  console.info("zqf result" + JSON.stringify(res.data));
}).catch((error: AxiosError) => {
  console.error("zqf error:" + JSON.stringify(error));
});

关键修改:

  • 移除了FormData中重复的file参数
  • 将文件包装为包含uri、type和name的对象格式
  • 字符串参数mubanUrl通过params传递

这样文件通过multipart/form-data上传,字符串参数通过URL query传递,符合HTTP标准。

回到顶部