使用react hook形式上传文件

问题描述 投票:0回答:2

我正在尝试使用 React Hook Form 上传 PDF 文件,前端使用 next.js,后端使用 node.js。

前端:

const FileUpload = () => {
  const [proof, setProof] = useState({})

  const onSubmit = async (values) => {
    try {
      const proof = values.proof[0]
      let { data } = await axios.post('/api/upload-file', {
        proof,
      })
      setProof(data)
    } catch (err) {
      console.log(err.response)
    }
  }

  <form onSubmit={handleSubmit(onSubmit)} className={styles['form']}>
        <label htmlFor="proof" className={styles['form-input-label']}>
          <input
            type="file"
            name="proof"
            {...register('proof')}
            placeholder=" "
            required
            className={`${
              errors.proof? styles['form-input-error'] : styles['form-input']
            }
                )`}
          />
          <span className={styles['form-input-placeholder']}>
            upload file
          </span>
        </label>
        <p className={styles['form-error']}>{errors.file?.message}</p>
        <button
          type="submit"
          className="btn"
          disabled={!isDirty || !isValid || loading}
        >
          {loading ? <LoadingOutlined spin /> : 'Upload File'}
        </button>
      </form>
    </>
  )
}

export default FileUpload

后端(/api/upload-file):

export const uploadFile = async (req, res) => {
  try {
    console.log(req.body) // => returns empty object (proof:({}))
    const { proof } = req.body
    if (!proof) return res.status(400).send('File missing')

    // prepare the file
    const base64Data = new Buffer.from(
      proof.replace(/^data:proof\/\w+;base64,/, ''),
      'base64'
    )

    const type = proof.split(';')[0].split('/')[1]

    // image bucket params
    const params = {
      Bucket: 's3-bucket',
      Key: `${nanoid()}.${type}`,
      Body: base64Data,
      ACL: 'public-read',
      ContentType: 'application/pdf',
    }

    // upload to s3
    s3.upload(params, (err, data) => {
      if (err) {
        console.log(err)
        res.sendStatus(400)
      }
      res.send(data)
    })
  } catch (err) {
    console.log(err)
    return res
      .status(400)
      .send(
        'An Error occured'
      )
  }
}

我无法将文件传递到后端,我得到的只是一个空对象。我尝试研究 axios 文档以及 React hook 表单文档,但无济于事。

我做错了什么?

谢谢你的帮助!!

reactjs file-upload axios next.js react-hook-form
2个回答
1
投票

您必须将内容类型设置为 multi-part/formdata 并创建一个 formData 对象以将文件内容发送到后端。您还必须在后端解析该文件 multi-part/formdata。查找 Multer 作为后端,并查找 formData 对象作为前端。


0
投票

我认为首先你应该使用postman或swagger测试你的api,尝试上传文件(如果有效),然后重新定义你的onsubmit。在这里,您实际上是在传递一个空对象,因为它是空的 constproof=values.proof[0] 让 { data } =等待 axios.post('/api/upload-file', { 证明, }) 设置证明(数据)

© www.soinside.com 2019 - 2024. All rights reserved.