HarmonyOS 鸿蒙Next 使用httpRequest上传图片实战

发布于 1周前 作者 eggper 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 使用httpRequest上传图片实战

背景: 项目API接收boundary。一开始尝试使用fileupload方法失败,这个方法貌似只能上传文件但无法按项目的API接收返回值,转变思路使用http.request.

1、注意需要构建上传文件使用的分隔符

  let boundary: string = `WebKitFormBoundary${FileUtil.generate15CharString()}`;

  private static  generate15CharString():string {
    const characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    let str = '';
    for (let i = 0; i < 15; i++) {
      // 随机选择characters字符串中的一个字符
      const randomChar = characters.charAt(Math.floor(Math.random() * characters.length));
      str += randomChar;
    }
    return str;
  }

2、打开文件读取到沙箱中

// 打开文件

    let file = fs.openSync(fileModel.localUrl, fs.OpenMode.READ_ONLY);
    const dateStr = (new Date().getTime()).toString()
    // 临时文件目录
    let newPath = context.cacheDir + `/${dateStr}.${fileModel.fileSuffix}`;
    // 转化路径
    fs.copyFileSync(file.fd, newPath);
    // 新的路径
    let realUri = "internal://cache/" + newPath.split("cache/")[1];

3、构建文字部分

// 构建文字部分
    let textContent: string = "";
    // 选择要上传的文件的内容
    let fileContent: ArrayBuffer = await FileUtil.readContentFromFile(newPath)
    // 上传请求的body内容
    let bodyContent = FileUtil.buildBodyContentNew(fileName, contentType, boundary, textContent, fileContent)

完整代码实例:

  public static async uploadFileNew<T>(fileModel: FileModel, uploadConfigModel: UploadConfigModel, callback: (result: T) => void) {
    // 获取上下文
    let context = getContext()
    // 打开文件
    let file = fs.openSync(fileModel.localUrl, fs.OpenMode.READ_ONLY);
    const dateStr = (new Date().getTime()).toString()
    // 临时文件目录
    let newPath = context.cacheDir + `/${dateStr}.${fileModel.fileSuffix}`;
    // 转化路径
    fs.copyFileSync(file.fd, newPath);
    // 新的路径
    let realUri = "internal://cache/" + newPath.split("cache/")[1];

    let contentType=FileUtil.getContentType(fileModel.fileSuffix);
    // return new Promise(async (resolve, reject) => {
    //   FileUtil.uploadFileCustom(uploadConfigModel.uploadUrl,newPath,uploadConfigModel.header,new Map<string, string>(),contentType)
    // });

    let resultData:string
    let fileName = `${newPath.split("cache/")[1]}`;
    // 上传文件使用的分隔符
    let boundary: string = `WebKitFormBoundary${FileUtil.generate15CharString()}`;
    // 构建文字部分
    let textContent: string = "";
    // 选择要上传的文件的内容
    let fileContent: ArrayBuffer = await FileUtil.readContentFromFile(newPath)
    // 上传请求的body内容
    let bodyContent = FileUtil.buildBodyContentNew(fileName, contentType, boundary, textContent, fileContent)
    let token=await AppConfig.getToken();
    let Fileheader = {
      "Authentication": token,
      "User-Agent":"123",
      "Content-Type":`multipart/form-data;boundary=----${boundary}`
    } as Filehearder
    //header['Content-Type']=`----${boundary}`;
    // http请求对象
    let httpRequest = http.createHttp();
    let opt: http.HttpRequestOptions = {
      method: http.RequestMethod.POST,
      header: Fileheader,
      extraData: bodyContent
    }
    // 发送上传请求
    httpRequest.request(uploadConfigModel.uploadUrl, opt)
      .then((resp) => {
        httpRequest.destroy();
        console.log(JSON.stringify(resp.result))
        resultData = resp.result as string
        let data2:T =JSON.parse(resultData) as T
        callback(data2);
      })
      .catch((e: BusinessError) => {
        console.log("uploadFile error:" + (e as BusinessError).message)
        httpRequest.off('headersReceive');
        httpRequest.destroy();
      })

  }



  private  static  getContentType(extension:string) {
    switch (extension.toLowerCase()) {
      case 'jpg':
      case 'jpeg':
        return 'image/jpeg';
      case 'png':
        return 'image/png';
      case 'docx':
        return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
      case 'xlsx':
        return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
      case 'pdf':
        return 'application/pdf';
      case 'doc':
        return 'application/msword';
    // 其他文件类型可以根据需要添加
      default:
        return 'application/octet-stream'; // 未知类型
    }
  }
  private static  generate15CharString():string {
    const characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    let str = '';
    for (let i = 0; i < 15; i++) {
      // 随机选择characters字符串中的一个字符
      const randomChar = characters.charAt(Math.floor(Math.random() * characters.length));
      str += randomChar;
    }
    return str;
  }

更多关于HarmonyOS 鸿蒙Next 使用httpRequest上传图片实战的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next 使用httpRequest上传图片实战的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS 鸿蒙Next系统中,使用httpRequest上传图片的实践记录可以如下进行:

首先,确保你已经在项目中引入了必要的网络请求库。在HarmonyOS中,你可以使用ohos.multimedia.Image类来处理图片,以及ohos.network.http.HttpRequestohos.network.http.HttpResponse类来发送HTTP请求。

将图片转换为字节数组,这是上传图片前的重要步骤。你可以使用Image类的getPixels方法获取图片的像素数据,并手动转换为字节数组,或者使用其他图片处理库来简化这一过程。

接下来,构建HTTP请求。创建一个HttpRequest对象,并设置其方法为POST。在请求体中,包含图片的字节数组以及必要的请求参数(如文件类型、文件名等)。

发送请求并处理响应。使用HttpRequestsend方法发送请求,并监听响应。在响应中,你可以检查状态码和响应体,以确定图片是否成功上传。

示例代码(简化):

Image image = ...; // 获取Image对象
byte[] imageData = ...; // 将Image转换为字节数组
HttpRequest request = new HttpRequest();
request.setMethod(HttpRequest.Method.POST);
request.setRequestBody(...); // 包含imageData和其他参数
request.send(new HttpRequest.Callback() {
    @Override
    public void onResponse(HttpRequest request, HttpResponse response) {
        // 处理响应
    }

    @Override
    public void onError(HttpRequest request, IOException e) {
        // 处理错误
    }
});

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部