Nuxt3服务器端如何获取FormData文件并转为Buffer存入第三方数据库?
问题解决步骤
前端代码修复
你的前端代码存在两个关键问题,会导致后端无法正确解析FormData:
- 手动设置
Content-Type: multipart/form-data丢失boundary信息:当fetch的body为FormData时,浏览器会自动生成带boundary的Content-Type头(例如multipart/form-data; boundary=----WebKitFormBoundaryxxx),手动设置会覆盖这个自动生成的头,导致后端无法分割表单数据。 - fetch请求未处理异步逻辑:
fetch是异步函数,直接读取response.status会拿到Promise对象而非实际状态码。
修改后的前端代码:
createFormData = (file: File): FileRequest => { const headers = new Headers({ // 移除手动设置的Content-Type,交给浏览器自动处理 "fileName": file.name, "fileType": file.type, // 补充文件类型到请求头 "fileTTL": "3600" // 根据实际需求设置TTL值 }) const formData = new FormData() formData.append("userFile", file, file.name); const requestData: FileRequest = { formData: formData, fileHeaders: headers } return requestData }
async function uploadFile(file: File) { // 改为async函数 const fileRequest = createFormData(file) const url = '/data/file/api/loader' try { const requestInit: RequestInit = { method: 'POST', body: fileRequest.formData, headers: fileRequest.fileHeaders } const response = await fetch(url, requestInit); // 添加await处理异步 return { status: response.status } } catch(error) { console.log("Error uploading file", error) return { status: 500 } } }
后端代码修复
Nuxt3中处理multipart/form-data需要使用readMultipartFormData而非readBody,同时要注意将文件数据转换为Buffer的方法:
import { InnoDB } from 'inno-db' export default defineEventHandler(async (event) => { // 读取multipart表单数据 const formData = await readMultipartFormData(event) if (!formData) { throw createError({ statusCode: 400, statusMessage: '未接收到表单数据' }) } // 定位到表单中的文件项 const fileItem = formData.find(item => item.name === 'userFile') if (!fileItem) { throw createError({ statusCode: 400, statusMessage: '表单中未找到文件' }) } // 获取请求头中的参数 const fileName = getRequestHeader(event, 'fileName') || fileItem.filename const fileType = getRequestHeader(event, 'fileType') || fileItem.type const fileTTL = getRequestHeader(event, 'fileTTL') || '3600' // 将文件的Uint8Array数据转换为Buffer const fileBuffer = Buffer.from(fileItem.data) // 创建数据库实例(修复原代码的语法错误,属性名需加引号) const dbFileInstance = new InnoDB({ id: InnoDB.autoGenerate, File: fileBuffer, FileName: fileName, 'Content-Type': fileType, TTL: fileTTL }) // 用Promise封装回调逻辑,避免回调地狱 try { await new Promise((resolve, reject) => { dbFileInstance.save((doc, err) => { if (err) reject(err) else resolve(doc) }) }) return { status: 200, message: '文件上传成功' } } catch (err) { console.error('数据库保存失败:', err) throw createError({ statusCode: 500, statusMessage: '文件保存到数据库失败' }) } })
额外注意事项
- 配置请求体大小限制:如果上传大文件,需要在
nuxt.config.ts中调整请求体大小限制:export default defineNuxtConfig({ server: { maxRequestBodySize: '10mb' // 根据实际文件大小调整 } }) - 确认数据库参数要求:如果
inno-db的File字段接受Blob或ArrayBuffer类型,可直接使用fileItem.data(Uint8Array可直接转换为这两种类型)。
内容的提问来源于stack exchange,提问作者BreenDeen
相关产品推荐
相关产品推荐

