我正在尝试了解 Nuxt /server API,但似乎无法弄清楚如何将带有表单数据(即文件)的 POST 请求发送到 Nuxt 服务器以转发到外部服务:
在我的
pages.vue
文件中我有这个方法:
async function onSubmit() {
const formData = new FormData();
for (let file of form.files) {
await formData.append("image", file);
}
await $fetch("/api/send", {
method: "POST",
body: formData
});
}
然后在
/server/api/send.js
我有:
export default defineEventHandler(async (event) => {
const { method } = event.node.req;
// I THINK THE ISSUE IS HERE
const body =
method !== "GET" && method !== "HEAD"
? await readMultipartFormData(event)
: undefined;
const response = await $fetch.raw(https://*******, {
method,
baseURL: *********,
headers: {
},
body: body
});
return response._data;
}
我正在使用 Nuxt 有效地创建一个直通 API,以便外部端点不会暴露给最终用户。只是无法弄清楚如何以正确的格式访问 formData 以在服务器端传递。我认为我不应该使用
readMultipartFormData()
,因为这似乎以某种方式解析数据,而我只想将 formData 直接传递到外部 API。有什么建议吗?
我尝试过同时使用
readMultipartFormData()
和 readBody()
,但似乎都不起作用。我实际上不需要阅读正文,而是获取它并在没有任何格式的情况下传递它......
我在这个问题上挣扎了很多,没有干净的方法,每次我必须使用 Nuxt 3 处理文件上传时,我只是使用 nuxt-proxy 前端绕过服务器,这也很难看......
proxy: {
options: {
target: 'https://my-backend.herokuapp.com',
changeOrigin: true,
pathRewrite: {
'^/api/mediaupload/': '/api/mediaupload/',
},
pathFilter: [
'/api/mediaupload/',
]
}
},
在我的页面中:
const addFiles = (e: { target: { files: any; }; }): void => {
console.log('e',e)
const formData = new FormData();
for (let i = 0; i < e.target.files.length; i++) {
formData.append("file"+i, e.target.files[i]);
}
formData.append("foo", bar);
refInput = formData
};
提交按钮:
const submitFiles = async () => {
domError.value = null
const token = useStatefulCookie('token')
if (token.value && refInput) {
const authorization = `Bearer ${token.value.access_token}`
const data = await $fetch("/api/mediaupload/", {
method: "POST",
body: refInput,
headers: {
// 'Content-Type': 'multipart/form-data', <- finally useless
'Authorization': authorization,
},
async onResponseError({ request, response, options }) {
domError.value = response._data
}
})
}
else return
}
如果您想将带有 formdata 的数据传递到端点,请尝试此库: https://www.npmjs.com/package/object-to-formdata
代码:
import { serialize } from 'object-to-formdata';
const formData = serialize(body);
const response = await $fetch.raw(https://*******, {
method,
baseURL: *********,
headers: {
},
body: formData
});
我设法让它与丑陋的解决方案一起工作,首先你必须将 nuxt 更新到版本 3.2.0 分钟,然后这是我的正面
let jobApplicationDTO = {
firstName: values.firstName,
lastName: values.lastName,
email: values.email,
phoneNumber: values.phoneNumber,
company: values.company,
shortDescription: values.shortDescription
};
const formData = new FormData();
formData.append("application", new Blob([JSON.stringify(jobApplicationDTO)], {type: "application/json"}));
formData.append("file", values.file) ;
//formData.append("file", values.file );
await useFetch("/api/application", {
method: "POST",
body: formData,
onResponse({request, response, options}) {
// Process the response data
if (response.status === 200) {
errorMessage.value = "";
successMessage.value = "Your application wa sent successfully, you will be contacted soon !";
}
},
onResponseError({request, response, options}) {
console.debug(response);
if (response.status === 400) {
successMessage.value = "";
errorMessage.value = "There may be an issue with our server. Please try again later, or send an email to [email protected]";
} else {
successMessage.value = "";
errorMessage.value = "Sorry we couldn’t send the message, there may be an issue with our server. Please try again later, or send an email to [email protected]";
}
},
});
}
和服务器端
import {FormData} from "node-fetch-native";
export default defineEventHandler(async (event) => {
const {BACKEND_REST_API, ENQUIRY_TOKEN} = useRuntimeConfig();
//retrieve frontend post formData
const form = await readMultipartFormData(event);
const applicationUrl = BACKEND_REST_API + '/job/apply'
console.log("url used for enquiry rest call :" + applicationUrl);
console.log("Job application token :" + ENQUIRY_TOKEN);
const formData = new FormData();
console.log(form);
if (form) {
formData.append(form[0].name, new Blob([JSON.stringify(JSON.parse(form[0].data))], {type: form[0].type}));
formData.append(form[1].name, new Blob([form[1].data], {type: form[1].type}), form[1].filename);
}
console.log(formData.values);
return await $fetch(applicationUrl, {
method: "POST",
body: formData,
headers: {
Authorization: ENQUIRY_TOKEN,
},
});
})
有趣的是在前端你必须创建一个 formData ,然后获取内容并从之前在 MultiFormPart[] 中转换的 formData 重新创建一个 formData ,我在 nuxt 上创建了一个票证以了解如何正确执行此操作