NyllRE / nuxt-file-storage

Easy solution to store files in your nuxt apps. Be able to upload files from the frontend and recieve them from the backend to then save the files in your project.
https://nuxt.com/modules/nuxt-file-storage
MIT License
63 stars 7 forks source link

Support for saving 'FormData' data formats #6

Closed nowo closed 2 months ago

nowo commented 3 months ago

When we upload files when using api tool for interface testing, we need to further process the data into base64, so I think the front end only transmits FormData data and the back end stores it.

  1. Add useFileStorage() return filesList,This is an array of file objects
  2. The server adds the storeFileFormData method for saving FormData data

Usage

Frontend

<template>
  <input type="file" @input="handleFileInput" />
  <button @click="submit">submit</button>
</template>

<script setup>
const { handleFileInput, filesList } = useFileStorage()

const submit = async () => {
  const formData= new FormData()
  Array.from(filesList.value).forEach((file)=>{
    formData.append('file', file)
  })
  // formData.append('file', filesList.value[0])  // upload single file
  const response = await $fetch('/api/files', {
    method: 'POST',
    body: formData
  })
}
</script>

Backend

export default defineEventHandler(async (event) => {
  const files = (await readMultipartFormData(event)) || []
  const file0 = files.find(item => item.name === 'file' && item.type)
  if(!file0) return 'no file'
  await storeFileFormData(
    file, // the stringified version of the file
    8,            // you can add a name for the file or length of Unique ID that will be automatically generated!
    '/userFiles'  // the folder the file will be stored in
  )

  return 'success!'
})
NyllRE commented 3 months ago
const submit = async () => {
  const formData= new FormData()
  Array.from(filesList.value).forEach((file)=>{
    formData.append('file', file)
  })
  // formData.append('file', filesList.value[0])  // upload single file
  const response = await $fetch('/api/files', {
    method: 'POST',
    body: formData
  })
}

I was thinking about the way you add files to the formdata object and I felt like it's too much work for the developer.

What if the filesList was a formData object and the fileSubmitHandler appended to that form data and the user was able to utilize that formData object?

nowo commented 3 months ago
const submit = async () => {
  const formData= new FormData()
  Array.from(filesList.value).forEach((file)=>{
    formData.append('file', file)
  })
  // formData.append('file', filesList.value[0])  // upload single file
  const response = await $fetch('/api/files', {
    method: 'POST',
    body: formData
  })
}

I was thinking about the way you add files to the formdata object and I felt like it's too much work for the developer.

What if the filesList was a formData object and the fileSubmitHandler appended to that form data and the user was able to utilize that formData object?

This seems to require the use of JSON.stringfy to convert strings.

  // *.vue
  formData.append('data', JSON.stringify({ msg: 'hello', value: 1 }))

  // server/**.ts
  const formData = await readFormData(event)
  const data = formData.get('data') as string
  const parseData = JSON.parse(data)  // { msg: 'hello', value: 1 }
NyllRE commented 3 months ago

@nowo so do you suggest that the formdata method should be differentiated from the default form list? maybe a different form data ref should be added in this case. if this is the way we are planning on doing it then we should:

what do you suggest in this process so we can make this package as easy to use as possible?

nowo commented 3 months ago

@NyllRE I think the separate way may be better. The data sent by these two methods are different. Your method can send object, while mine is more formal and conforms to the writing habits of most people. It just needs a little more code maintenance, and I can help you maintain it if you need to

The name filesList might not even bother me. Some people might not even use the useFileStorage method. The file objects come from other methods or components. Let's make the distinction clear in the documentation. If you want to change it, let's change it. I can't think of any good words, you know😂

NyllRE commented 2 months ago

Hey @nowo , I decided to make the documentation to a refactored version of this project based on your suggested changes first then implement it, this is what I currently have in mind. please feel free to comment on whatever you think is fitting :)

Nuxt File Storage Docs Button

nowo commented 2 months ago

Looks great. I can close this then.

The problem with readMultipartFormData is that it cannot accept data from large files,I read the relevant content, I did not find a solution.

I'm sorry. I should have told you the first time. I apologize for submitting this code. It's sudden and I didn't consider it carefully myself. I have other ideas that I will discuss with you in Discussions