javascript - 使用 multer 将多个文件发送到谷歌存储桶 - 为什么我的文件是空的?
问题描述
我之前设置了一个文件上传并正常工作。现在我需要让它处理多个文件。
这是我现在的代码:
const multer = require('multer')
const { Storage } = require('@google-cloud/storage')
const storage = new Storage()
const m = multer({ storage: multer.memoryStorage() })
module.exports = app => {
app.use('/', router)
router.post(
'/reader-:shortId/file-upload',
passport.authenticate('jwt', { session: false }),
m.array('files'),
async function (req, res) {
const bucketName = req.params.shortId.toLowerCase()
await storage.createBucket(bucketName)
bucket = storage.bucket(bucketName)
let promises = []
req.files.forEach((file) => {
const blob = bucket.file(file.originalname)
const newPromise = new Promise((resolve, reject) => {
blob.createWriteStream({
metadata: { contentType: file.mimetype }
}).on('finish', async response => {
await blob.makePublic()
resolve(response)
}).on('error', err => {
reject('upload error: ', err)
}).end()
})
promises.push(newPromise)
})
Promise.all(promises).then((response) => {
// the response I get here is [undefined, undefined]
res.status(200).send(response)
}).catch((err) => {
res.status(400).send(err.message)
});
})
}
req.files 确实给了我一个文件数组,带有一个缓冲区和一个有意义的大小。承诺全部解决。但是一旦我检查了谷歌存储桶中的文件,它们的名称是正确的,但没有任何内容(大小为 0)
正如我之前所说,当我使用一个文件(使用 m.single('file')
我不想将存储桶用作 multer 设置的目的地,因为在上传到谷歌存储桶之前我还必须更改文件名。
编辑:这是谷歌云文档为单个文件上传提供的代码示例(https://cloud.google.com/nodejs/getting-started/using-cloud-storage):
function sendUploadToGCS (req, res, next) {
if (!req.file) {
return next();
}
const gcsname = Date.now() + req.file.originalname;
const file = bucket.file(gcsname);
const stream = file.createWriteStream({
metadata: {
contentType: req.file.mimetype
},
resumable: false
});
stream.on('error', (err) => {
req.file.cloudStorageError = err;
next(err);
});
stream.on('finish', () => {
req.file.cloudStorageObject = gcsname;
file.makePublic().then(() => {
req.file.cloudStoragePublicUrl = getPublicUrl(gcsname);
next();
});
});
stream.end(req.file.buffer);
}
我最初有类似的工作,但我只是不明白它从哪里获取文件缓冲区数据。这可能是多个文件的不同之处。
解决方案
我知道为时已晚,但有人可能会寻找在 Google Cloud Storage 上上传多个文件的答案。
依赖项:
- 表达
- 谷歌云库
- 穆尔特
- 身体解析器
这是控制器代码。
exports.post_image_upload = async (req, res) => {
/** Check if file exist */
if (!req.files) {
res.status(400).send('No file uploaded.');
return;
}
let PublicUrls = []
req.files.forEach((file) => {
const blob = bucket.file(file.fieldname + '-' + Date.now() + path.extname(file.originalname))
const blobStream = blob.createWriteStream({
metadata: { contentType: file.mimetype }
})
blobStream.on('finish', ()=> {
blob.makePublic()
})
blobStream.on('error', err => {
//Put your error message here
})
blobStream.end(file.buffer)
const Url = `https://storage.googleapis.com/${bucket.name}/${blob.name}`
PublicUrls.push(Url)
})
res.send(PublicUrls)
}
祝你好运
推荐阅读
- symfony-forms - Symfony 表单集合 - 保持与主键的关联
- docker - 尝试使用 bitbucket 管道在 docker 中调用服务的 url
- google-app-engine - Google App Engine - 使用外部目录中的种子文件部署?
- python - 从 urllib 和 Postman 调用时,Flask 服务器收到的 POST 请求数据的差异
- vue.js - vue-cli 默认单元测试“Unexpected token {”错误
- java - 将 EventFiringWebDriver 与 RemoteWQebDriver 一起使用
- c# - https Web 服务中缺少 _vti_bin/ListData.svc/$metadata
- android - 微调器下拉在约束布局中的底部导航视图上重叠
- sharepoint - SharePoint - 显示修改的讨论列表项的重复搜索结果
- reactjs - Babel 7 Typescript 属性未定义