使用EJS模板渲染图片时Express服务器崩溃的问题排查
问题:Express+Mongoose+EJS项目中产品详情页图片加载触发CastError
我是Express JS、MongoDB新手,正在使用Mongoose ODM、ExpressJS和EJS模板引擎搭建简单在线购物应用。现有Product模型和根据动态路由获取产品详情的控制器,但在EJS模板中访问产品图片时遇错误。
Product模型
import { Schema, model } from 'mongoose'; const productSchema = new Schema({ title: String, imgurl: String, price: Number, description: String, userID: { type: Schema.Types.ObjectId, ref: 'user', }, }); export const Product = model('Product', productSchema);
产品详情控制器
export function getProductDetails(req, res, next) { return Product.findById(req.params.id) .then(({ _doc }) => res.render('shop/details', { _doc })) .catch(console.log); }
EJS模板
<!DOCTYPE html> <html lang="en"> <head> <title>Details</title> </head> <body> <h1><%= _doc.imgurl %></h1> <img src="<%= _doc.imgurl %>" alt="" /> </body> </html>
错误信息
CastError: Cast to ObjectId failed for value "fasdf" (type string) at path "_id" for model "Product"
{ "messageFormat": undefined, "kind": "ObjectId", "value": "fasdf", "path": "_id", "reason": "BSONError: input must be a 24 character hex string, 12 byte Uint8Array, or an integer" }
问题详情
在EJS模板的img标签src属性中使用_doc.imgurl时出现上述CastError,但在h1标签中使用该值无问题,期望服务器不崩溃并正确渲染页面。
解决方案
1. 调整路由顺序,避免静态资源被动态路由捕获
错误中的fasdf不是合法的MongoDB ObjectId,说明有请求将无效字符串当作产品ID传入了findById。大概率是静态资源路由和产品详情动态路由顺序颠倒,导致图片请求被动态路由拦截(比如请求/products/fasdf.jpg时,fasdf.jpg被当作ID传入)。
修复方法:将静态资源路由放在动态路由之前:
// 先挂载静态资源路由 app.use(express.static('public')); // 再挂载产品详情动态路由 app.get('/products/:id', getProductDetails);
2. 完善控制器的错误处理与ID校验
当前控制器仅打印错误未做处理,会导致请求挂起或服务器崩溃。需要添加ID格式校验和错误响应:
import mongoose from 'mongoose'; export function getProductDetails(req, res, next) { // 先校验ID格式是否合法 if (!mongoose.Types.ObjectId.isValid(req.params.id)) { return res.status(404).render('404', { message: '产品不存在' }); } return Product.findById(req.params.id) .then((product) => { if (!product) { return res.status(404).render('404', { message: '产品不存在' }); } // 直接传递product对象,EJS中调用更直观 res.render('shop/details', { product }); }) .catch(err => { console.log(err); res.status(500).render('500', { message: '服务器错误' }); }); }
3. 优化EJS模板的图片路径与变量调用
确保图片路径为静态资源目录下的绝对路径(比如/images/product.jpg),同时简化变量调用:
<!DOCTYPE html> <html lang="en"> <head> <title>Details</title> </head> <body> <h1><%= product.imgurl %></h1> <img src="<%= product.imgurl %>" alt="<%= product.title %>" /> </body> </html>
内容的提问来源于stack exchange,提问作者GOURAB MUKHERJEE
相关产品推荐
相关产品推荐

