Node.js使用multer上传文件到Firebase报file未定义错误如何解决
错误原因
你当前触发ReferenceError: file is not defined的核心问题有两个:
- 你直接把
FirebaseService.uploadFileToFirebaseStore( file , fileName );写在了multer配置文件的顶层作用域,这个文件只要被项目其他代码引入加载,就会立刻执行这行代码,此时还没有任何文件上传请求触发,file和fileName两个变量完全没有被定义,直接调用就会抛出未定义错误。 - multer配置代码中还残留了无效字符
enter code here,会导致语法报错。
解决步骤
1. 修正multer配置文件
删除顶层的Firebase上传调用和无效字符,修改后配置如下:
const multer = require('multer'); const path = require('path'); const storage = multer.diskStorage({ destination:function(req, file ,cb){ cb(null, './uploads' ); }, filename: function(req, file ,cb){ cb(null, new Date().getTime() + path.extname(file.originalname)); } }); const fileFilter = (req, file ,cb) => { if(file.mimetype === 'image/jpeg' ||file.mimetype === 'image/png'){ cb(null,true); }else{ cb(new Error('Unsupported file'), false); } } const upload = multer({ storage: storage, limits: { fileSize:1024*1024*10 }, fileFilter:fileFilter }); module.exports= { upload:upload }
注意:需要提前在项目根目录创建uploads文件夹,否则本地存储文件时会抛出路径不存在错误。如果不需要本地留存文件,可以将diskStorage替换为内存存储multer.memoryStorage(),减少本地磁盘占用。
2. 安装Koa适配的multer版本
原生multer是为Express设计的,在Koa中需要安装@koa/multer才能正常获取上传的文件:
npm i @koa/multer
3. 添加上传路由
在user.routes.js中引入依赖,新增文件上传路由,只有当请求触发这个路由时,才会执行文件上传逻辑,此时才能拿到有效的file对象:
const Router = require("@koa/router"); const { insertUserApi, getAllUsersApi, getUserApi, updateUserApi, deleteUserApi, } = require("../api/user.api"); // 新增引入 const { upload } = require('../multer配置文件的相对路径'); const FirebaseService = require("../service/firebase.service"); const router = new Router({ prefix: "/api/user", }); // 新增文件上传路由,单文件上传,表单字段名设为avatar,可根据需求修改 router.post("/uploadAvatar", upload.single('avatar'), async (ctx) => { const file = ctx.file; const fileName = file.filename; // 此时调用Firebase上传接口 const uploadRes = await FirebaseService.uploadFileToFirebaseStore(file, fileName); ctx.status = 200; ctx.body = { msg: '上传成功', fileUrl: uploadRes // 这里替换为Firebase返回的文件访问地址 } }) // 原有路由保持不变 router.post("/add", async (ctx) => { let user = ctx.request.body; user = await insertUserApi(user); ctx.response.status = 200; ctx.body = user; }); // ... 剩余原有路由逻辑保持不变 module.exports = router;
其他注意事项
你当前的用户插入逻辑存在参数不匹配问题:user.dao.js中的insertUser方法需要接收firstName、lastName、username、password四个参数,但user.api.js中的insertUserApi只传入了firstName、lastName,如果需要存储用户关联的头像地址,还需要在用户表新增对应字段,将Firebase返回的文件地址存入用户信息中。
内容的提问来源于stack exchange,提问作者ShewaniPerera
相关产品推荐
相关产品推荐

