我正在尝试使用 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 表单文档,但无济于事。
我做错了什么?
谢谢你的帮助!!
您必须将内容类型设置为 multi-part/formdata 并创建一个 formData 对象以将文件内容发送到后端。您还必须在后端解析该文件 multi-part/formdata。查找 Multer 作为后端,并查找 formData 对象作为前端。
我认为首先你应该使用postman或swagger测试你的api,尝试上传文件(如果有效),然后重新定义你的onsubmit。在这里,您实际上是在传递一个空对象,因为它是空的 constproof=values.proof[0] 让 { data } =等待 axios.post('/api/upload-file', { 证明, }) 设置证明(数据)