“哇,这行得通,为什么会这样呢?我目前正在使用Express-Handlebars(3.1.0),在我的express应用程序中将其设置为渲染引擎。” –李文刚1月12日14:13
“过去,Handlebars允许您从模板访问输入对象的原型方法和属性...这种行为产生了多个安全问题...在handlebars@^4.6.0中,可以访问对象原型。现在,如果您将自定义类用作Handlebars的输入,则您的代码将无法再使用...该软件包会自动将运行时选项添加到每个模板调用中,从而禁用安全限制... 如果您的用户正在编写模板,并且在服务器上执行它们,则不应使用此程序包,而应寻找其他方法来解决问题...我建议您先将类实例转换为普通的JavaScript对象,然后再将其传递给模板函数。您访问的每个属性或功能都必须是其父级的“自有属性”。” –自述文件
此处有更多详细信息:https :
//www.npmjs.com/package/@handlebars/allow-prototype-access
快速和肮脏的保险方法
用法(express-handlebars
和mongoose
):
express-handlebars
不允许您指定运行时选项以传递给模板函数。该软件包可以帮助您禁用模型的原型检查。
“如果您完全控制服务器中执行的模板,则只能这样做。”
脚步:
1-安装依赖性
npm i @handlebars/allow-prototype-access
2-使用此代码段作为示例来重写您的快速服务器
const express = require('express');
const mongoose = require('mongoose');
const Handlebars = require('handlebars');
const exphbs = require('express-handlebars');
// Import function exported by newly installed node modules.
const { allowInsecurePrototypeAccess } = require('@handlebars/allow-prototype->access');
const PORT = process.env.PORT || 3000;
const app = express();
const routes = require('./routes');
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static('public'));
// When connecting Handlebars to the Express app...
app.engine('handlebars', exphbs({
defaultLayout: 'main',
// ...implement newly added insecure prototype access
handlebars: allowInsecurePrototypeAccess(Handlebars)
})
);
app.set('view engine', 'handlebars');
app.use(routes);
const MONGODB_URI = process.env.MONGODB_URI || >'mongodb://localhost/dbName';
mongoose.connect(MONGODB_URI);
app.listen(PORT, function () {
console.log('Listening on port: ' + PORT);
});
3-运行服务器,然后跳舞。
更安全的方法
在将AJAX调用返回的对象传递到Handlebars模板之前,请将其映射到具有您需要在.hbs
文件中访问的每个属性或函数的新对象。在下面,您可以看到在将新对象传递到Handlebars模板之前制作的新对象。
const router = require("express").Router();
const db = require("../../models");
router.get("/", function (req, res) {
db.Article.find({ saved: false })
.sort({ date: -1 })
.then(oldArticleObject => {
const newArticleObject = {
articles: oldArticleObject.map(data => {
return {
headline: data.headline,
summary: data.summary,
url: data.url,
date: data.date,
saved: data.saved
}
})
}
res.render("home", {
articles: newArticleObject.articles
})
})
.catch(error => res.status(500).send(error));
});
您的猫鼬查询
如果我错了,请纠正我,但我认为这可能对您的查询有用...
Confession.find()
.sort({ date: -1 })
.then(function (oldDoc) {
for (var i = 0; i < oldDoc.length; i++) {
//Check whether sender is anonymous
if (oldDoc[i].from === "" || oldDoc[i].from == null) {
oldDoc[i].from = "Anonymous";
}
//Add an extra JSON Field for formatted date
oldDoc[i].formattedDate = formatTime(oldDoc[i].date);
}
const newDoc = {
doc: oldDoc.map(function (data) {
return {
from: data.from,
formattedDate: data.formattedDate
}
})
}
res.render('index', { title: 'Confession Box', success: req.session.success, errors: req.session.errors, confession: newDoc.doc });
req.session.errors = null;
req.session.success = null;
});