繁体   English   中英

无法将多部分表单数据从 React 正确发送到 Express Js

[英]Unable to send the multi part form data from React to Express Js correctly

我正在尝试使用 Dropzone 上传文件并将这些文件从 React JS 发送到 java 后端 API。 这里 React 是将文档发送到 express 后端并添加一些键,然后将最终的表单数据发送到后端 java 端点。 但无法在后端获取文件和请求部分。 快递正在获取错误的数据格式感谢任何帮助。

UploadMyFiles.jsx

const UploadMyFiles = () => {

  const [selectedFiles, setSelectedFiles]= useState(null)
  const [userName,setUserName]=userState('TestUser')

  const handleUserFileUpload = (userSelectedFiles) => {
        setSelectedFiles(userSelectedFiles)  

    const formData = new FormData()

    formData.append('files', selectedFiles)
    formData.append('userName', userName,)
    const { res} = sendDocument(formData) //refer reactTest.js module below

  }

  return (

          <div className='myClass'>Select Bill</div>
          <Dropzone
            accept={'.pdf'}
            onDrop={selectedFiles => handleUserFileUpload (selectedFiles)}
          >
            {({ getRootProps, getInputProps }) => (<div {...getRootProps()} id='no-padding'>
              <input
                {...getInputProps()}
                type='file'
                id='attachments'
                name='attachments'
                className='myclass'
              />              
            
            </div>
            )}
          </Dropzone>
  )
}
export default UploadMyFiles

reactTest.js

export const sendDocument = async (myFormData) => {
  return await axios({
    method: 'post',
    url: `/sendDocument`,
    data: myFormData,
    headers: { 'Content-Type': 'multipart/form-data' }
  });
};

expressTest.Js 模块 [Node JS]

const express = require('express')
const axios = require('axios')
const router = express.Router()

router.post('/', (req, res) => {
  console.log(req.body) //see **output below, File data is in string format which is causing the wrong format in my axios router call to backend. How do I get actual file instead of this [object File]. I beliver it is because of multer bodyparser
  console.log(JSON.parse(req.body.myFormData.userName))
  axios({
    method: 'post',
    url: '/sendMyUserData',
    data: req.body,
    headers: {
      apiKey: 'keytoapi'
      //'Content-Type': 'multipart/form-data'
    }
  })
    .then(response => {
      
      return res.send(res)
    })
    .catch(error => {
      console.error('error')
     }

**console.log 的输出

{"files":"[object File]","userName":"TestUser"}

如您所见,“文件”数据是字符串格式,这导致我的 Axios 路由器调用后端的“数据”格式错误。 如何获取实际文件而不是此 [目标文件]? 我相信这是因为 multer bodyparser。

我的后端 Java 端点

@PostMapping(path = "/sendMyUserData", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
        public String uploadMyUserData(@RequestPart(value = "files") final MultipartFile[] multipartFiles, @RequestPart(value = "userName", required = true) String userName ) {
            return myService.storeFiles(multipartFiles, userName));
    }

例外:

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=utf-8' not supported

我尝试在 expressTest.js 模块中设置内容类型,但我在后端端点中获取了所有 null 值

'Content-Type': 'multipart/form-data;

在此处输入图像描述

完整的请求标头 - 从浏览器网络选项卡的请求中捕获

Request URL: http://localhost:8080/sendMyUserData
Referrer Policy: strict-origin-when-cross-origin
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,te;q=0.8
Authorization:mytoken
Connection: keep-alive
Content-Length: 83474
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvooZbILex2ARkOrs
Cookie: Host: localhost:8080
Origin: http://localhost:8080
Referer: http://localhost:8080/sendDocument
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.114 Safari/537.36
------WebKitFormBoundaryvooZbILex2ARkOrs
Content-Disposition: form-data; name="userName"

TestUser
------WebKitFormBoundaryvooZbILex2ARkOrs
Content-Disposition: form-data; name="files"; filename="Xyz.pdf"
Content-Type: application/pdf

问题是FormDataappend方法采用字符串或单个文件作为值,并且“如果没有指定这些值,则将值转换为字符串”。 但是,您正在传递一个文件数组selectedFiles ),它被字符串化为"[object File]" (如果一次选择两个文件,它将是[object File],[object File] - 正是Array.prototype.toStringObject.prototype.toString做)。

你需要做

const UploadMyFiles = () => {
  const [userName,setUserName] = userState('TestUser')
  const handleUserFileUpload = (selectedFiles) => {
    const formData = new FormData()
    for (const file of selectedFiles)
      formData.append('files', file)
    formData.append('userName', userName)
    sendDocument(formData).catch(…)
  }

  return (
    <div className='myClass'>Select Bill</div>
      <Dropzone
        accept={'.pdf'}
        onDrop={handleUserFileUpload}
      >…</Dropzone>
    </div>
  )
}

浏览器网络选项卡在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM