「これでうまくいきましたが、なぜこれが起こっているのですか?現在、Expressアプリのレンダリングエンジンとして設定したExpress-handlebars(3.1.0)を使用しています。」– Lee Boon Kong Jan 12 at 14:13
「以前は、ハンドルバーを使用して、テンプレートから入力オブジェクトのプロトタイプメソッドとプロパティにアクセスできました。この動作から複数のセキュリティ問題が発生しました... handlebars@^4.6.0では、オブジェクトプロトタイプへのアクセスカスタムクラスをハンドルバーへの入力として使用すると、コードは機能しなくなります...このパッケージは、各テンプレート呼び出しにランタイムオプションを自動的に追加し、セキュリティ制限を無効にします ... ユーザーがテンプレートをサーバーで実行する場合は、このパッケージを使用するのではなく、問題を解決する他の方法を見つけてください...テンプレートインスタンスに渡す前に、クラスインスタンスをプレーンJavaScriptオブジェクトに変換することをお勧めします。アクセスするすべてのプロパティまたは関数は、その親の「独自のプロパティ」である必要があります。」– README
詳細はこちら: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
ファイル内でアクセスする必要がある各プロパティまたは関数を使用して、オブジェクトを新しいオブジェクトにマップします。以下に、ハンドルバーテンプレートに渡す前に作成された新しいオブジェクトを示します。
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;
});