问题
I am using a Nodejs backend with server-side rendering using handlebars.
After reading a doc
array of objects from handlebars, which contains key "content" and "from".
However when I try to use #each
to loop through the array of objects,
the error "Handlebars: Access has been denied to resolve the property "from" because it is not an "own property" of its parent" appears.
I've tried to console.log() the data that I've fetched in the doc array and everything seems fine.
For some perspective, this is the mongoose query,
I've added the object doc as a key inside the res.render arguments.
Confession.find()
.sort({date: -1})
.then(function(doc){
for(var i=0; i < doc.length; i++){
//Check whether sender is anonymous
if (doc[i].from === "" || doc[i].from == null){
doc[i].from = "Anonymous";
}
//Add an extra JSON Field for formatted date
doc[i].formattedDate = formatTime(doc[i].date);
}
res.render('index', {title: 'Confession Box', success:req.session.success, errors: req.session.errors, confession: doc});
req.session.errors = null;
req.session.success = null;
});
This is the portion of .hbs file I am trying to loop through:
{{#each confession}}
<div class="uk-card uk-card-default uk-card-body uk-margin uk-align-center uk-width-1-2@m" >
<div class="uk-text-bold">Message: </div>
<div>{{this.content}}</div>
<div>From: {{this.from}}</div>
<div>Posted: {{this.formattedDate}}</div>
</div>
{{/each}}
回答1:
i solve this issue by installing a dev dependency for handlebars
npm i -D handlebars@4.5.0
回答2:
try npm install handlebars versio 4.5.3
npm install handlebars@4.5.3
回答3:
There was a breaking change in the recent release of Handlebars which has caused this error.
You could simply add the configurations they suggest in their documentation, however be aware, depending on you implementation, this could lead the vulnerability to XXS and RCE attacks.
https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access
Confession.find()
.sort({date: -1})
.then(function(doc){
for(var i=0; i < doc.length; i++){
//Check whether sender is anonymous
if (doc[i].from === "" || doc[i].from == null){
doc[i].from = "Anonymous";
}
//Add an extra JSON Field for formatted date
doc[i].formattedDate = formatTime(doc[i].date);
}
res.render('index', {title: 'Confession Box', success:req.session.success, errors: req.session.errors, confession: doc}, {
// Options to allow access to the properties and methods which as causing the error.
allowProtoMethodsByDefault: true,
allowProtoPropertiesByDefault: true
});
req.session.errors = null;
req.session.success = null;
});
回答4:
Today I have the same warning from handlebars and the view is empty. Below is how I fixed that:
// * USERS PAGE
// @description users route
// @returns ../views/users.hbs
router.get('/users', async (req, res) => {
// get all items from db collection
const collection = 'User'
await dbFindAllDocs(collection) // <=> wrapper for Model.find() ...
.then(documents => {
// create context Object with 'usersDocuments' key
const context = {
usersDocuments: documents.map(document => {
return {
name: document.name,
location: document.location
}
})
}
// rendering usersDocuments from context Object
res.render('users', {
usersDocuments: context.usersDocuments
})
})
.catch(error => res.status(500).send(error))
})
the users.hbs file
<ul>
{{#each usersDocuments}}
<li>name: {{this.name}} location: {{this.location}}</li>
{{/each}}
</ul>
Creating an entire new Object named context
with its own properties then pass in it into the render function will fix the issue...
note:
When we do not create a new Object, it is easy to accidentally expose confidential information, or information that could compromise the security of the projet, mapping the data that's returned from the database and passing only what's needed onto the view could be a good practice...
来源:https://stackoverflow.com/questions/59690923/handlebars-access-has-been-denied-to-resolve-the-property-from-because-it-is