# http请求通过MultiFormData分片上传报错

#### 问题现象

通过http.MultiFormData\[\]上传失败，错误信息：

```
{"timestamp":1747124996117,"status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'chunk' is not present","path":"/upload/clip"}
```

#### 背景知识

httpRequest实现分片上传需要服务器那边配合定义好协议传参，在MultiFormData里添加相关参数。

#### 问题定位

这是传参错误导致,错误示例如下:

```
uploadFile1(filePath: string) {
  let httpRequest = http.createHttp();
  let requestMultipart: http.MultiFormData[] = [];
  let formData: http.MultiFormData = {
    name: 'xxx.mp4',
    contentType: 'video/mp4',
    filePath: filePath,
    remoteFileName: 'xxx.mp4',
    data: {
      'vid': 'xxx',
      'fseq': 'xxx',
      'cmd5': 'xxx',
      'chunk': ''
    }
  };
  requestMultipart.push(formData);
  httpRequest.request(
    this.uploadUrl,
    {
      method: http.RequestMethod.POST,
      header: {
        'Content-Type': 'multipart/form-data',
        'APPID': 'xxx',
        'TOKEN': 'xxx',
        'VERSION': 'xxx',
      },
      multiFormDataList: requestMultipart,
    }, (err: BusinessError, data: http.HttpResponse) => {
    if (err) {
      console.error(`Failed to uploadFile. Code: ${err.code}, message: ${err.message}`);
      return;
    }
    console.info(`Succeeded to uploadFile:  ${data}`);
  });
}
```

应把data数据放到requestMultipart中。

#### 分析结论

数据结构不对导致服务器无法捕获引起错误，修改传参可解决处理。

#### 修改建议

通过对象requestMultipart上传时需要把data数据拎出来单独push到requestMultipart对象里面才能收到。

```
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  private uploadUrl: string = ''; //替换为实际服务器URL。

  uploadFile(filePath: string) {
    let httpRequest = http.createHttp();
    let requestMultipart: http.MultiFormData[] = [];
    let formData: http.MultiFormData = {
      name: 'share.txt', //数据名称。
      contentType: 'text/plain', //数据类型，自API 11开始支持该属性。
      filePath: filePath, //替换为实际文件路径。
      remoteFileName: 'share.txt', //上传到服务器保存为文件的名称。
    };
    requestMultipart.push(formData);

    httpRequest.request(
      this.uploadUrl,
      {
        method: http.RequestMethod.POST,
        header: {
          'Content-Type': 'multipart/form-data',
        },
        multiFormDataList: requestMultipart,
      }, (err: BusinessError, data: http.HttpResponse) => {
      if (err) {
        console.error(`Failed to uploadFile. Code: ${err.code}, message: ${err.message}`);
        return;
      }
      console.info(`Succeeded to uploadFile:  ${data.result}`);
    });
  }

  build() {
    Column({ space: 10 }) {
      Button('MultiFormData分片上传').onClick(() => {
        let context = this.getUIContext()?.getHostContext();
        if (!context) {
          return;
        }
        let filePath = context.filesDir + '/' + 'share.txt'; //文件沙箱路径，使用时替换实际文件路径。
        this.uploadFile(filePath);
      });
    }
    .height('100%')
    .width('100%');
  }
}
```

#### 常见FAQ

Q：使用requestInStream设置multiFormDataList上传文件，当remoteFileName的名字过长时会提示500，换成其他短文件名则不会出现问题。

A：使用multiFormDataList设置remoteFileName时，当文件名包含中文、空格、特殊符号或长度超过255字符，可能触发服务器端异常，需通过URL编码处理。

Q：multiFormDataList上传文件的filePath字段能使用fd吗？

A：filePath中需要传入一个文件路径，而fd://int的语法是以fd标识一个媒体资源，非文件路径。