ExpressJS:TypeError:无法读取未定义的属性“路径”尝试将文件上传到 cloudinary 并将 url 保存到 mongoDB
Posted
技术标签:
【中文标题】ExpressJS:TypeError:无法读取未定义的属性“路径”尝试将文件上传到 cloudinary 并将 url 保存到 mongoDB【英文标题】:ExpressJS: TypeError: Cannot read property 'path' of undefined When trying to upload a file to cloudinary and save the url to mongoDB 【发布时间】:2021-06-20 15:01:37 【问题描述】:我正在尝试将文件上传到 cloudinary 并通过 POST 请求将 url 保存到 mongodb
我的前端代码如下所示:
<form action="/add-product?_csrf=<%=csrfToken%>" class="form-control col s12" method="POST" enctype="multipart/form-data">
<div class="row">
<div class="input-field">
<label for="title">Name</label>
<br>
<input type="text" id="name" name="name" required>
</div>
</div>
<div class="row">
<div>
<% if (categories.length > 0) %>
<label for="category"><h5>Category</h5></label>
<select id="status" name="status">
<% categories.forEach(category => %>
<option value="category"><%= category.category %></option>
<% ) %>
</select>
<% else %>
<p>There are no categories to select</p>
<% %>
</div>
</div>
<div class="row">
<div class="input-field" id="ckeditor">
<h5>Product Description</h5>
<textarea id="body" name="description"></textarea>
</div>
</div>
<div class="row">
<div class="input-field">
<label for="image"> Upload Product Image</label>
<br>
<br>
<input type="file" name="image">
</div>
</div>
<div class="row">
<div class="input-field">
<label for="price">Price</label>
<br>
<input type="number" id="price" name="price">
</div>
</div>
<div class="row">
<input type="submit" value="Save" class="btn">
<a href="/" class="btn orange">Cancel</a>
</div>
</form>
我在快递服务器上这个页面的路由:
//get the link to add a product to the eccomerce application using a GET request
router.get('/add-product', ensureAuth, csrfProtection, async (req,res) =>
try
const categories = await Category.find().sort(createdAt:-1)
//console.log(categories)
res.render('addproduct',categories:categories,csrfToken:req.csrfToken())
catch (err)
console.error(err)
res.render('error/500')
)
//post the filled form
router.post('/add-product',ensureAuth, parseForm, csrfProtection,async (req,res)=>
try
// Upload image to cloudinary
console.log(req)
console.log(req.file)
const result = await cloudinary.uploader.upload(req.file.path, function(err,res)
console.error(err);
);
//assert the populate db relationship
req.body.user = req.user.id
let Product = new product(
category: req.body.category,
name: req.body.name,
image: result.secure_url,
description:req.body.description,
price:req.body.price,
)
await Product.save()
res.redirect('/')
catch (err)
console.error(err)
res.render('error/500')
)
但是在填写表单字段后尝试发布请求时,我收到错误:
undefined
TypeError: Cannot read property 'path' of undefined
at router.post (/home/e-wave/Desktop/nodecommerce/routes/eroutes.js:131:62)
at Layer.handle [as handle_request] (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/layer.js:95:5)
at next (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/route.js:137:13)
at csrf (/home/e-wave/Desktop/nodecommerce/node_modules/csurf/index.js:117:5)
at Layer.handle [as handle_request] (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/layer.js:95:5)
at next (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/route.js:137:13)
at urlencodedParser (/home/e-wave/Desktop/nodecommerce/node_modules/body-parser/lib/types/urlencoded.js:100:7)
at Layer.handle [as handle_request] (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/layer.js:95:5)
at next (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/route.js:137:13)
at ensureAuth (/home/e-wave/Desktop/nodecommerce/middleware/auth.js:4:20)
at Layer.handle [as handle_request] (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/layer.js:95:5)
at next (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/layer.js:95:5)
at /home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/e-wave/Desktop/nodecommerce/node_modules/express/lib/router/index.js:335:12)
这里是我所有必需的导入和配置: 对于 utils 和 cloudinary.js 文件夹中的 cloudinary 配置:
const cloudinary = require("cloudinary").v2;
const cloudStorage = require('multer-storage-cloudinary');
const dotenv = require('dotenv').config(path:__dirname+'/.env');
cloudinary.config(
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET,
);
module.exports = cloudinary
然后我将这个模块导入到 routes.js 文件中,如下所示:
const cloudinary = require("../utils/cloudinary");
请问我做错了什么?
PS:当我将我的 req.file 记录到控制台时,我变得未定义。
【问题讨论】:
从您的示例中,req.file
看起来是空的 - 您使用什么中间件来填充它?我猜想像multer?请注意,multer-storage-cloudinary
有助于自动将文件上传到 Cloudinary,但在这种情况下,您通常不会直接从您自己的代码中调用 Cloudinary 的 SDK(multer-storage-cloudinary
会隐含地为您执行此操作)。基于此,我认为您可能正在混合两种不同的集成方法
非常感谢@Igy,我可以通过使用 multer 中间件来填充 req.file 字段,然后再将任何数据放入其中来解决问题!
【参考方案1】:
问题解决了,显然我没有使用任何中间件(在这种情况下是 multer)来管理上传的文件。
代码sn-p
我必须在 utils 文件夹中创建一个 multer.js 文件
它将包含代码
const multer = require("multer");
const path = require("path");
// Multer config
module.exports = multer(
storage: multer.diskStorage(),
fileFilter: (req, file, cb) =>
let ext = path.extname(file.originalname);
if (ext !== ".jpg" && ext !== ".jpeg" && ext !== ".png")
cb(new Error("File type is not supported"), false);
return;
cb(null, true);
,
);
然后在 express 服务器文件夹中需要这个模块
const upload = require("../utils/multer");
然后在 add-product POST 请求中添加为中间件
router.post('/add-product', upload.single("image"),ensureAuth, parseForm, csrfProtection,async (req,res)=>
try
// Upload image to cloudinary
const result = await cloudinary.uploader.upload(req.file.path);
//assert the populate db relationship
req.body.user = req.user.id
let Product = new product(
category: req.body.category,
name: req.body.name,
image: result.secure_url,
description:req.body.description,
price:req.body.price,
)
await Product.save()
res.redirect('/')
catch (err)
console.error(err)
res.render('error/500')
)
【讨论】:
以上是关于ExpressJS:TypeError:无法读取未定义的属性“路径”尝试将文件上传到 cloudinary 并将 url 保存到 mongoDB的主要内容,如果未能解决你的问题,请参考以下文章
ExpressJS:TypeError:无法读取未定义的属性“路径”尝试将文件上传到 cloudinary 并将 url 保存到 mongoDB