使用axios的POST请求将JSON数据作为multipart/form-data发送

3
以下API可以在Postman中使用:

POST request that accepts from the backend

Spring boot,后端代码:

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@Slf4j
public class UploadFile {
    @Autowired
    private FTPClient con;

    @PostMapping("/api/auth/uploadfiles")
    public String handleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {

        try {
            boolean result = con.storeFile(file.getOriginalFilename(), file.getInputStream());

            redirectAttributes.addFlashAttribute("message",
                    "You successfully uploaded " + file.getOriginalFilename() + "!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            redirectAttributes.addFlashAttribute("message",
                    "Could not upload " + file.getOriginalFilename() + "!");
        }
        return "redirect:/";
    }
}

ReactJS,前端代码:我在this.state.ipData中有一个对象数组。
  exportFTP = async () => {
    
      const fromdata = this.state.ipData;
      alert("Data Send to FTP server");

    axios({
      method: 'post',
      url: 'http://localhost:8080/api/auth/uploadfiles',
      data: fromdata,
      header: {
        'Accept': 'application/json ,text/plain, */*',
        'Content-Type': 'multipart/form-data',
        //'Authorization': 'Bearer '+JWTToken,
      },
    })
  }
<button
  style={{ marginRight: "2%", marginTop: "0.25%" }}
  type="button"
  className="btn btn-info"
  onClick={() => this.exportFTP()}
>
  Export to FTP
</button>

我需要更改我的前端(ReactJS)代码,使其像我使用Postman发送POST请求一样。当前的JS代码导致以下错误响应:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Current request is not a multipart request] with root cause

请注意,当使用Postman时API可以正常工作。如何修复JS代码?

我尝试使用表单数据,但我确切地不知道如何在我的状态中处理这些数据。 - user11725933
它保存了组件的当前状态和一些数组数据。 - user11725933
是的,我认为我需要那个数组来转换JSON文件或其他什么东西,但我找不到任何有用的资源。 - user11725933
1
(5557) [{...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}] - user11725933
2个回答

2
尝试删除头部并发送请求。
    exportFTP = async () => {
    
      const fromdata = this.state.ipData;
      alert("Data Send to FTP server");

    axios({
      method: 'post',
      url: 'http://localhost:8080/api/auth/uploadfiles',
      data: fromdata
    }).then(function (res) {
      if (res.ok) {
        alert("Perfect! ");
      } else if (res.status == 401) {
        alert("Oops! ");
      }
    }, function (e) {
      alert("Error submitting form!");
    });
}

感谢您关注我的问题。但是,我仍然从后端收到相同的错误。 - user11725933

2
你正在以多部分请求中的Blob形式发送JSON数据。因此,你需要使用Blob API。
创建一个从JSON数据创建Blob的函数:
function jsonBlob(obj) {
  return new Blob([JSON.stringify(obj)], {
    type: "application/json",
  });
}

并在请求中使用此函数:

exportFTP = async () => {
  const formData = new FormData();
  formData.append("file", jsonBlob(this.state.ipData))

  axios({
    method: "post",
    url: "http://localhost:8080/api/auth/uploadfiles",
    data: formData,

    /* You had a Typo: it is "headers" not "header".
    And, multipart/form-data header should get set automatically 
    as we used FormData. You might not need to add that manually. */
    // You may also not need Accept header; (should be set automatically).
    
    headers: { 
      Accept: "application/json ,text/plain, */*",
      "Content-Type": "multipart/form-data",
      // 'Authorization': 'Bearer '+ JWTToken,
    },
  });
};

1
这确实有效,有没有什么方法可以减小jsonBlob的大小? - user11725933
在路径为[]的上下文中,servlet [dispatcherServlet] 的 Servlet.service() 抛出了异常[请求处理失败;嵌套异常是 org.springframework.web.multipart.MaxUploadSizeExceededException: 超过最大上传大小;嵌套异常是 java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: 文件字段超过其允许的最大大小 1048576 字节。],根本原因是... - user11725933
我在本地机器上使用了一个运行在Apache FTP服务器上的程序。但是我的代码中没有添加任何限制。 - user11725933
1
非常感谢,我刚刚在application.properties中添加了以下内容:spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB现在它可以正常工作了。 - user11725933
是的,您是正确的:Spring Boot中MultipartFile的最大限制 - Ajeet Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接