文档管理中心
FAQ系统开发网络网络(Network)http请求通过MultiFormData分片上传报错

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

问题现象

通过http.MultiFormData[]上传失败,错误信息:

收起
自动换行
深色代码主题
复制
  1. {"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里添加相关参数。

问题定位

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

收起
自动换行
深色代码主题
复制
  1. uploadFile1(filePath: string) {
  2. let httpRequest = http.createHttp();
  3. let requestMultipart: http.MultiFormData[] = [];
  4. let formData: http.MultiFormData = {
  5. name: 'xxx.mp4',
  6. contentType: 'video/mp4',
  7. filePath: filePath,
  8. remoteFileName: 'xxx.mp4',
  9. data: {
  10. 'vid': 'xxx',
  11. 'fseq': 'xxx',
  12. 'cmd5': 'xxx',
  13. 'chunk': ''
  14. }
  15. };
  16. requestMultipart.push(formData);
  17. httpRequest.request(
  18. this.uploadUrl,
  19. {
  20. method: http.RequestMethod.POST,
  21. header: {
  22. 'Content-Type': 'multipart/form-data',
  23. 'APPID': 'xxx',
  24. 'TOKEN': 'xxx',
  25. 'VERSION': 'xxx',
  26. },
  27. multiFormDataList: requestMultipart,
  28. }, (err: BusinessError, data: http.HttpResponse) => {
  29. if (err) {
  30. console.error(`Failed to uploadFile. Code: ${err.code}, message: ${err.message}`);
  31. return;
  32. }
  33. console.info(`Succeeded to uploadFile: ${data}`);
  34. });
  35. }

应把data数据放到requestMultipart中。

分析结论

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

修改建议

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

收起
自动换行
深色代码主题
复制
  1. import { http } from '@kit.NetworkKit';
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. @Entry
  4. @Component
  5. struct Index {
  6. private uploadUrl: string = 'http://127.0.0.1:9588/'; //替换为实际服务器URL
  7. uploadFile(filePath: string) {
  8. let httpRequest = http.createHttp();
  9. let requestMultipart: http.MultiFormData[] = [];
  10. let formData: http.MultiFormData = {
  11. name: 'share.txt', //数据名称。
  12. contentType: 'text/plain', //数据类型,自API 11开始支持该属性。
  13. filePath: filePath, //替换为实际文件路径。
  14. remoteFileName: 'share.txt', //上传到服务器保存为文件的名称。
  15. };
  16. requestMultipart.push(formData);
  17. httpRequest.request(
  18. this.uploadUrl,
  19. {
  20. method: http.RequestMethod.POST,
  21. header: {
  22. 'Content-Type': 'multipart/form-data',
  23. },
  24. multiFormDataList: requestMultipart,
  25. }, (err: BusinessError, data: http.HttpResponse) => {
  26. if (err) {
  27. console.error(`Failed to uploadFile. Code: ${err.code}, message: ${err.message}`);
  28. return;
  29. }
  30. console.info(`Succeeded to uploadFile: ${data.result}`);
  31. });
  32. }
  33. build() {
  34. Column({ space: 10 }) {
  35. Button('MultiFormData分片上传').onClick(() => {
  36. let context = this.getUIContext()?.getHostContext();
  37. if (!context) {
  38. return;
  39. }
  40. let filePath = context.filesDir + '/' + 'share.txt'; //文件沙箱路径,使用时替换实际文件路径。
  41. this.uploadFile(filePath);
  42. });
  43. }
  44. .height('100%')
  45. .width('100%');
  46. }
  47. }

常见FAQ

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

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

Q:multiFormDataList上传文件的filePath字段能使用fd吗?

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

在 FAQ 中进行搜索
请输入您想要搜索的关键词