Google Cloud Function(Node.js)文件上传异常排查求助
嘿,我明白你作为Cloud Functions新手遇到这个问题的 frustration!本地跑好好的,部署就失效,确实挺闹心的。咱们一步步来排查解决这个req.file为undefined的问题:
1. 先检查请求的核心要求
Multer的upload.single('avatar')有两个硬性要求,没满足的话直接拿不到文件:
- 前端上传的表单字段名必须严格是
avatar,不能打错字或者用别的名字 - 请求的Content-Type必须是
multipart/form-data,不能是application/json或者其他类型
你可以用curl快速测试下:
curl -X POST -F "avatar=@/本地文件路径/比如test.jpg" https://你的云函数URL/upload
如果这个测试能拿到文件,那问题大概率在前端请求的配置上;如果还是不行,继续往下看。
2. 修正Cloud Functions的Express入口配置
你代码里的app.listen();是多余的!Cloud Functions不需要你手动启动服务器,它会自动处理请求路由。这行代码可能导致部署后的路由无法正确映射,赶紧删掉,换成Cloud Functions的导出方式:
首先在代码顶部引入firebase-functions:
const functions = require('firebase-functions');
然后把app.listen();替换成:
exports.app = functions.https.onRequest(app);
同时别忘了在package.json里添加这个依赖(版本用最新的就行):
"firebase-functions": "^4.9.0"
3. 移除冲突的依赖
你的package.json里同时装了express-fileupload和multer——这俩都是处理文件上传的中间件,会抢着解析multipart请求!结果就是multer拿不到请求体,自然req.file就是undefined。
赶紧把express-fileupload删掉:
npm uninstall express-fileupload
然后把package.json里对应的依赖项也移除。
4. 临时目录的小确认(可选,但能排除问题)
Cloud Functions的/tmp目录确实是可读写的,你的diskStorage配置没问题,但可以先换成内存存储测试下,确认是不是磁盘存储的问题:
const upload = multer({ storage: multer.memoryStorage() });
如果换成内存存储能拿到req.file,那再换回diskStorage就行,一般不会有问题。
修改后的完整代码示例
index.js
const express = require('express'); const multer = require('multer'); const path = require('path'); const functions = require('firebase-functions'); var storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/') }, filename: function (req, file, cb) { cb(null, Date.now() + path.extname(file.originalname)) } }); var upload = multer({ storage: storage }); const app = express(); app.post('/upload', upload.single('avatar'),(req, res,next) => { // 增加错误处理,方便调试 if (!req.file) { return res.status(400).send('未上传名为"avatar"的文件'); } console.log(req.file); const filePath = req.file.path; console.log(typeof (filePath)); res.status(200).send(filePath); }); exports.app = functions.https.onRequest(app);
package.json
{ "name": "Puputer", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.17.1", "multer": "^1.4.2", "puppeteer": "^3.0.1", "puppeteer-page-proxy": "^1.2.3", "firebase-functions": "^4.9.0" } }
最后,重新部署你的Cloud Functions,再测试应该就能正常拿到req.file啦!
内容的提问来源于stack exchange,提问作者Roman Hrybinchuk

