file-uploadmultipartform-datanuxt3.jsnitro

How do I process form data for a file upload as FormData on the server side of a Nuxt 3 handler application


I am sending data to a Nuxt 3 server side defineEventHandler. The data is correctly sent to it as a multipart/form content-type. However, I want to get the data in the FormData sent to defineEventHandler but when I use readMultipartFormDat(event) to get the payload, I get undefined. How can I can get the file contents to upload to a 3rd party database that can store MS Excel files by supplying it with a Buffer or Blob or ArrayBuffer of the file contents. Here is how I create the fetch request.

createFormData = (file: File): FileRequest => {
  const headers = new Headers({
    "Content-Type": "multipart/form-data",
    "fileName": file.name,
  }) 
  const formData = new FormData()
  formData.append("userFile", file, file.name);
  const requestData: FileRequest = {
    formData: formData,
    fileHeaders: headers
  }
  return requestData 
}

This is the code that actually sends the code to the server side component

function uploadFile(file: File) {
  const fileRequest =  createFormData(file)
  const url = '/data/file/api/loader' 
        
  try {
    const requestInit: RequestInit = {
      method: 'POST',
      body: fileRequest.formData,
      headers: fileRequest.fileHeaders
    }
    const response = fetch(url, requestInit);
    return {
      status: response.status
    }
  } catch(error) {
    console.log("Error uploading file", error)
  }
}

Finally, the fetch sends data to this component which is responsible for storing the upload file in the proprietary document database.

This is server/api/loader.ts so the fetch url is /data/file/api/loader as NUXT_APP_BASE_URL=/data/file

import { InnoDB } from 'inno-db'
export default defineEventHandler(async (event) => {
  // Do not know how to get the FormData from payload
  const payload = await readBody(event)
            
  const fileName  = getRequestHeader(event, 'fileName')
  const fileType  = getRequestHeader(event, 'fileType')
  const fileTTL  =  getRequestHeader(event, 'fileTTL')

  const dbFileInstance = new InnoDb(
    id: InnoDB.autoGenerate,
    // I need to get the FormData file contents as a Buffer  
    File: Buffer, 
    FileName: fileName,
    Content-Type: fileType,
    TTL: fileTTL
  )
  dbFileInstance.save((doc, err) => {
    // Log and Handle errors
  })
})

I would appreciate if someone can point me to how to obtain the FormData from the payload and convert it to a Buffer object the database contents


Solution

  • I found the issue. Adding the Content-Type header in the method to create the FormData results in the browser not sending the boundary prefix i.e. boundary=---WebKitxxxxx etc. I modified the creation like so and that worked

    
                   createFormData = (file:File): 
                      FileRequest => {
         
                      const headers = new Headers({
                      'fileName': file.name,
                     }) 
                      const formData = new FormData()
                      formData.append("userFile", file, file.name);
                      const requestData:FileRequest = {
                         formData: formData,
                         fileHeaders: headers
                     }
                       return requestData 
                   }
    
    
    

    Notice that 'Content-Type': 'multipart/form-data' is not included here.