Express JS API request.主体显示缓冲区数据



我创建了一个API:

app.post("/categories", async (req, res) => {
console.log(`req.body: ${JSON.stringify(req.body)}`)
console.log(`req.body.title: ${JSON.stringify(req.body.title)}`)
console.log(`req.files: ${JSON.stringify(req.files)}`)
res.json({})
});

其中数据传递是:

{
"title": "Video Title"
"description": "Video Description"
"thumbnail": [object File]
"video": [object File]
}

传递的数据由VueJSAxios供电:

methods: {
async createCategory() {
const formData = new window.FormData();
formData.set("title", this.category.title);
formData.set("description", this.category.description);
formData.set("thumbnail", this.thumbnail);
formData.set("video", this.video);
await $this.axios.post("clothing/v1/categories/", formData, {
headers: { "Content-Type": "multipart/form-data" },
});
}
}

然而,在请求中显示的数据。身体:

req.body: {"type":"Buffer","data":[45,45,45,45,45,45,87,101,98,75,105,116,70,111,114,109,66,111,117,110,100,97,114,121,121,104,112,52,54,97,82,89,68,121,77,82,57,66,52,110,13,10,67,111,110,116,101,110,116,45,68,105,115,112,111,115,105,116,105,111,110,58,32,102,111,114,109,45,100,97,116,97,59,32,110,97,109,101,61,34,116,105,116,108,101,34,13,10,13,10,86,105,100,101,111,32,84,105,116,108,101,13,10,45,45,45,45,45,45,87,101,98,75,105,116,70,111,114,109,66,111,117,110,100,97,114,121,121,104,112,52,54,97,82,89,68,121,77,82,57,66,52,110,13,10,67,111,110,116,101,110,116,45,68,105,115,112,111,115,105,116,105,111,110,58,32,102,111,114,109,45,100,97,116,97,59,32,110,97,109,101,61,34,100,101,115,99,114,105,112,116,105,111,110,34,13,10,13,10,86,105,100,101,111,32,68,101,115,99,114,105,112,116,105,111,110,13,10,45,45,45,45,45,45,87,101,98,75,105,116,70,111,114,109,66,111,117,110,100,97,114,121,121,104,112,52,54,97,82,89,68,121,77,82,57,66,52,110,13,10,67,111,110,116,101,110,116,45,68,105,115,112,111,115,105,116,105,111,110,58,32,102,111,114,109,45,100,97,116,97,59,32,110,97,109,101,61,34,116,104,117,109,98,110,97,105,108,34,13,10,13,10,91,111,98,106,101,99,116,32,70,105,108,101,93,13,10,45,45,45,45,45,45,87,101,98,75,105,116,70,111,114,109,66,111,117,110,100,97,114,121,121,104,112,52,54,97,82,89,68,121,77,82,57,66,52,110,13,10,67,111,110,116,101,110,116,45,68,105,115,112,111,115,105,116,105,111,110,58,32,102,111,114,109,45,100,97,116,97,59,32,110,97,109,101,61,34,118,105,100,101,111,34,13,10,13,10,91,111,98,106,101,99,116,32,70,105,108,101,93,13,10,45,45,45,45,45,45,87,101,98,75,105,116,70,111,114,109,66,111,117,110,100,97,114,121,121,104,112,52,54,97,82,89,68,121,77,82,57,66,52,110,45,45,13,10]}

我希望我能在我的API中检索我传递的数据,比如:req.body: {"title":"Example","description":"example"},因为我将使用这些数据保存在FireStore中并上传云存储中的文件。

注意:我尝试使用multer,但得到以下错误:

>      return fn.apply(this, arguments);
>                ^
>
>  TypeError: Cannot read properties of undefined (reading 'apply')
>      at Immediate.<anonymous> (/Users/adminadmin/Desktop/projects/dayanara-environments/dayanara-clothing-api/functions/node_modules/express/lib/router/index.js:641:15)
>      at processImmediate (node:internal/timers:468:21)

我没有提到我正在使用Google Cloud Functions开发NodeJS,并且只在本地和测试开发。

每当我的代码中出现任何错误时,下面的错误总是显示出来。

>      return fn.apply(this, arguments);
>                ^
>
>  TypeError: Cannot read properties of undefined (reading 'apply')
>      at Immediate.<anonymous> (/Users/adminadmin/Desktop/projects/dayanara-environments/dayanara-clothing-api/functions/node_modules/express/lib/router/index.js:641:15)
>      at processImmediate (node:internal/timers:468:21)

对于multipart,我使用busboy,如下所示:

app.post("/categories", (req, res) => {
let writeResult;
const storageRef = admin.storage().bucket(`gs://${storageBucket}`);
const busboy = Busboy({headers: req.headers});
const tmpdir = os.tmpdir();
// This object will accumulate all the fields, keyed by their name
const fields = {};
// This object will accumulate all the uploaded files, keyed by their name.
const uploads = {};
// This code will process each non-file field in the form.
busboy.on('field', (fieldname, val) => {
/**
*  TODO(developer): Process submitted field values here
*/
console.log(`Processed field ${fieldname}: ${val}.`);
fields[fieldname] = val;
});
const fileWrites = [];
// This code will process each file uploaded.
busboy.on('file', (fieldname, file, {filename}) => {
// Note: os.tmpdir() points to an in-memory file system on GCF
// Thus, any files in it must fit in the instance's memory.
console.log(`Processed file ${filename}`);
const filepath = path.join(tmpdir, filename);
uploads[fieldname] = filepath;
const writeStream = fs.createWriteStream(filepath);
file.pipe(writeStream);
// File was processed by Busboy; wait for it to be written.
// Note: GCF may not persist saved files across invocations.
// Persistent files must be kept in other locations
// (such as Cloud Storage buckets).
const promise = new Promise((resolve, reject) => {
file.on('end', () => {
writeStream.end();
});
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});
fileWrites.push(promise);
});
// Triggered once all uploaded files are processed by Busboy.
// We still need to wait for the disk writes (saves) to complete.
busboy.on('finish', async () => {
console.log('finished busboy')
await Promise.all(fileWrites);
/**
* TODO(developer): Process saved files here
*/
for (const file in uploads) {
const filePath = uploads[file]
const name = fields.name.replaceAll(' ', '-')
const _filePath = filePath.split('/')
const fileName = _filePath[_filePath.length - 1]
const destFileName = `${name}/${fileName}`
// eslint-disable-next-line no-await-in-loop
const uploaded = await storageRef.upload(filePath, {
destination: destFileName
})
const _file = uploaded[0];
const bucketFile = "https://firebasestorage.googleapis.com/v0/b/" + storageBucket + "/o/" + encodeURIComponent(_file.name) + "?alt=media"
fields[file] = bucketFile
}
writeResult = await admin
.firestore()
.collection(collection)
.add({ 
name: fields.name,
description: fields.description,
timestamp: admin.firestore.Timestamp.now(),
thumbnail: fields.thumbnail,
video: fields.video
});
const written = await writeResult.get();
res.json(written.data());
}
});

然后我需要改变如何从我的VueJS和Axios传递formData,在我的文件数据上我使用model替换为refs。我只需要使用modelDjango所以我认为这将是相同的ExpressJS:

methods: {
async createCategory() {
const formData = new window.FormData();
const thumbnail = this.$refs.thumbnail;
const video = this.$refs.video;
formData.set("name", this.category.name);
formData.set("description", this.category.description);
formData.set("thumbnail", thumbnail.files[0]);
formData.set("video", video.files[0]);
await $this.axios.post("clothing/v1/categories/", formData, {
headers: { "Content-Type": "multipart/form-data" },
});
}
}

在上面的更改之后,我终于可以发送multi-part/form-data properly了。下面的资源对我帮助很大:

  • https://cloud.google.com/functions/docs/samples/functions-http-form-data functions_http_form_data-nodejs
  • 使用Express在云函数中处理多部分/表单-数据POST

相关内容

  • 没有找到相关文章

最新更新