当前位置: 首页 > 知识库问答 >
问题:

把手:拒绝访问以解析属性“from”,因为它不是其父级的“自己的属性”

归翔
2023-03-14

我使用Nodejs后端与服务端渲染使用句柄。从句柄读取对象的doc数组,其中包含关键的内容和"from"。但是,当我尝试使用#each循环通过对象数组时,会出现错误"句柄:访问已被拒绝解析属性"from",因为它不是其父级的"own属性"。

我试着安慰你。log()我在doc数组中获取的数据,一切似乎都很好。

从某种角度来看,这是mongoose查询,
我在res.render参数中添加了object doc作为键。

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;
  });

这是我试图循环通过的. hbs文件的一部分:

 {{#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}}

共有3个答案

尹弘壮
2023-03-14

“哇,这成功了,为什么会这样?我目前正在使用快速把手(3.1.0),我在我的快速应用程序中设置它作为渲染引擎。”-李文刚1月12日14:13

“在过去,Handlebar会允许您从模板中访问输入对象的原型方法和属性...这种行为带来了多个安全问题...在handlebar@^4.6.0中,对对象原型的访问已被完全禁用。现在,如果您使用自定义类作为Handlebar的输入,您的代码将不再工作...这个包会自动为每个模板调用添加运行时选项,禁用安全限制...如果您的用户正在编写模板,并且您在服务器上执行它们,您不应该使用这个包,而是寻找其他方法来解决问题...我建议您在将类实例传递给模板函数之前将它们转换为普通的JavaScript对象。您访问的每个属性或函数必须是其父级的“自己的属性”。"-README

更多详情请点击此处:https://www.npmjs.com/package/@把手/允许原型进入

用法(快速把手猫鼬):

不允许您指定要传递给模板函数的运行时选项。这个包可以帮助您禁用模型的原型检查。

"只有在完全控制服务器中执行的模板的情况下才能这样做。"

步骤:

1-安装依赖项

允许原型访问

2-以这个片段为例重写express服务器

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调用返回的对象传递到Handlebar模板之前,将它映射到一个新对象中,其中包含您需要在. hbs文件中访问的每个属性或函数。下面您可以看到在将新对象传递到Handlebar模板之前制作的新对象。

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;
    });
傅峻
2023-03-14

我通过为车把安装一个dev依赖项来解决这个问题

npm i-Dhandlebars@4.5.0

农飞尘
2023-03-14

如果使用猫鼬,这个问题可以通过使用解决。lean()获取json对象(而不是mongoose对象):

dbName.find({}).lean()
  // execute query
  .exec(function(error, body) {
     //Some code
  });
 类似资料:
  • 问题内容: 我正在使用带有手柄的服务器端渲染的Nodejs后端。从车把读取一组对象后,其中包含键“ content”和“ from”。但是,当我尝试使用循环遍历对象数组时,会出现错误“ Handlebars:访问已被拒绝以解析属性”来自”,因为它不是其父项的“拥有的属性”。 我试图将我在doc数组中获取的数据进行console.log(),一切似乎都很好。 从某种角度来说,这是猫鼬查询,我已经将对

  • 问题内容: 考虑以下简化数据: 还有一个车把模板: 这是行不通的,因为在循环中,父作用域是不可访问的-至少不能以我尝试过的任何方式。我希望有办法做到这一点! 问题答案: 有两种有效的方法可以实现此目的。 取消引用父范围 通过在属性名称前添加前缀,可以引用父作用域。 您可以通过重复来提高多个级别。例如,要上两个级别,请使用。 取消引用根范围 通过添加到属性路径,您可以从最高范围向下导航(如cabal

  • 新并行/分布式计算和有问题的客户端服务器程序,我试图写。应该发生的是,服务器从客户端接收一个整数,并将总和发送回所有通向它的数字(例如,用户输入5,服务器计算1 2 3 4 5,服务器发送回15)。我还在试图弄清楚,所以我在客户端对输入进行了硬编码。 这就是我在服务器端所拥有的: 在客户端: 我也在客户端实现了接口。 我在客户端遇到的错误是: 异常线程"main"java.security.Acc

  • 问题内容: 因此,我只是试图创建一个通过gmail进行导航并自动执行某些任务的代码。我设法成功自动登录到GMail,但是尝试登录页面源时登录后仍然遇到此错误代码。 错误代码 Java代码 注意:我使用的是最新版的Firefox和最新版的Selenium PS:关于类似问题,我经历了11个以上的不同问题,没有人提供明确的解决方案,答案也非常模糊。 问题答案: 伙计们,我很久以前就找到了解决此问题的方

  • 我复制示例代码的一部分,仅用于图像标记。当我在上运行时,得到以下错误消息:-

  • 问题内容: 是否可以从函数范围内访问python函数对象属性? 例如让我们 现在,如果要返回_x属性内容“ foo”,则必须是什么?如果有可能(简单) 谢谢 更新: 我也想做以下工作: 更新2: 声明不可能(如果是这种情况),以及为什么,比提供一种方法来伪造它更令人满意,例如使用不同于函数的对象 问题答案: 解 使函数的默认参数之一成为对函数本身的引用。 用法示例: 说明 原始张贴者想要一种不需要