英文:
How do I process form data for a file upload as FormData on the server side of a Nuxt 3 handler application
问题
Sure, here's the translation of your code:
我正在向一个 Nuxt 3 服务器端的 `defineEventHandler` 发送数据。数据已正确以 `multipart/form` 的内容类型发送到它。但是,我想在 `FormData` 中获取发送到 `defineEventHandler` 的数据,但当我使用 `readMultipartFormData(event)` 来获取负载时,我得到了 undefined。我如何才能获取文件内容,以供给第三方数据库,该数据库可以存储 MS Excel 文件,并提供 `Buffer`、`Blob` 或 `ArrayBuffer` 的文件内容。以下是我创建 fetch 请求的方式。
这是实际将代码发送到服务器端组件的代码:
```javascript
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)
}
}
最后,fetch 发送数据到这个组件,该组件负责将上传的文件存储在专有文档数据库中。
这是 server/api/loader.ts
,因此 fetch URL 是 /data/file/api/loader
,因为 NUXT_APP_BASE_URL=/data/file
。
import { InnoDB } from 'inno-db';
export default defineEventHandler(async (event) => {
// 不知道如何从负载中获取 FormData
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,
// 我需要将 FormData 文件内容作为 Buffer 获取
File: Buffer,
FileName: fileName,
ContentType: fileType,
TTL: fileTTL
});
dbFileInstance.save((doc, err) => {
// 记录和处理错误
});
});
如果有人能指导我如何从负载中获取 FormData
并将其转换为数据库内容的 Buffer
对象,我将不胜感激。
<details>
<summary>英文:</summary>
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.
```javascript
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
答案1
得分: 2
你可以简化你的API调用方式。在以下示例中,我将使用$fetch
,在这种情况下,它将检测到你正在发送FormData
,并自动添加相应的标头。
所以,这是执行你的API调用的函数。
async function uploadFile(file: File) {
const formData = new FormData()
formData.append('file', file)
const response = await $fetch('/data/file/api/loader', {
method: 'post',
body: formData,
})
// 等等...
}
通过这样做,服务器端的readMultipartFormData
应该按预期工作。你可以尝试在服务器端获取文件。
export default defineEventHandler(async (event) => {
const files = await readMultipartFormData(event)
console.log(files)
})
英文:
You can simplify the way your are performing your API call. In the following example I'll be using $fetch
which in that case will detect that you're sending a FormData
and will automatically add the corresponding header.
So, here's the function to perform your API call.
async function uploadFile(file: File) {
const formData = new FormData()
formData.append('file', file)
const response = await $fetch('/data/file/api/loader', {
method: 'post',
body: formData,
})
// etc...
}
By doing so, on the server side the readMultipartFormData
should work as expected. You can try to get the file on the server side.
export default defineEventHandler(async (event) => {
const files = await readMultipartFormData(event)
console.log(files)
})
答案2
得分: 1
我发现了问题。在创建 FormData 的方法中添加 Content-Type 头部会导致浏览器不发送边界前缀,即 boundary=---WebKitxxxxx 等。我修改了创建方式,如下所示,这样可以正常工作:
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
}
请注意,这里没有包括 'Content-Type': 'multipart/form-data'。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论