2

我在在线运行 heroku 示例应用程序时遇到问题,它在本地运行良好,但在 heroku 上它显示此错误:

TypeError: /app/views/index.ejs:7
    5|     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes" />
    6| 
 >> 7|     <title><%= app.name %></title>
    8|     <link rel="stylesheet" href="stylesheets/screen.css" media="Screen" type="text/css" />
    9|     <link rel="stylesheet" href="stylesheets/mobile.css" media="handheld, only screen and (max-width: 480px), only screen and (max-device-width: 480px)" type="text/css" />
    10| 

Cannot read property 'name' of undefined
    at Object.<anonymous> (eval at <anonymous> (/app/node_modules/ejs/lib/ejs.js:198:12))
    at Object.<anonymous> (/app/node_modules/ejs/lib/ejs.js:200:15)
    at ServerResponse._render (/app/node_modules/express/lib/view.js:422:21)
    at ServerResponse.render (/app/node_modules/express/lib/view.js:315:17)
    at /app/web.js:49:11
    at [object Object].me (/app/node_modules/faceplate/index.js:114:7)
    at /app/web.js:48:18
    at /app/node_modules/faceplate/index.js:104:7
    at EventEmitter.<anonymous> (/app/node_modules/faceplate/index.js:131:11)
    at EventEmitter.emit (events.js:70:17)

我在某处读到 package.json 中的依赖项可能存在问题,所以这是我的 package.json 文件:

{
  "name":    "facebook-template-node",
  "version": "0.0.1",

  "description": "Template app for Heroku / Facebook integration, Node.js language",

  "dependencies": {
    "async":     "0.1.18",
    "ejs":       "0.4.3",
    "express":   "2.4.6",
    "faceplate": "0.6.x"
  },

  "engines": {
    "node": "0.6.x"
  }
}

这是 web.js 的代码:

var async   = require('async');
var express = require('express');
var util    = require('util');

// create an express webserver
var app = express.createServer(
  express.logger(),
  express.static(__dirname + '/public'),
  express.bodyParser(),
  express.cookieParser(),
  // set this to a secret value to encrypt session cookies
  express.session({ secret: process.env.SESSION_SECRET || 'secret123' }),
  require('faceplate').middleware({
    app_id: process.env.FACEBOOK_APP_ID,
    secret: process.env.FACEBOOK_SECRET,
    scope:  'user_likes,user_photos,user_photo_video_tags'
  })
);

// listen to the PORT given to us in the environment
var port = process.env.PORT || 3000;

app.listen(port, function() {
  console.log("Listening on " + port);
});

app.dynamicHelpers({
  'host': function(req, res) {
    return req.headers['host'];
  },
  'scheme': function(req, res) {
    return req.headers['x-forwarded-proto'] || 'http';
  },
  'url': function(req, res) {
    return function(path) {
      return app.dynamicViewHelpers.scheme(req, res) + app.dynamicViewHelpers.url_no_scheme(req, res)(path);
    }
  },
  'url_no_scheme': function(req, res) {
    return function(path) {
      return '://' + app.dynamicViewHelpers.host(req, res) + (path || '');
    }
  },
});

function render_page(req, res) {
  req.facebook.app(function(err, app) {
    req.facebook.me(function(user) {
      res.render('index.ejs', {
        layout:    false,
        req:       req,
        app:       app,
        user:      user
      });
    });
  });
}

function handle_facebook_request(req, res) {

  // if the user is logged in
  if (req.facebook.token) {

    async.parallel([
      function(cb) {
        // query 4 friends and send them to the socket for this socket id
        req.facebook.get('/me/friends', { limit: 4 }, function(friends) {
          req.friends = friends;
          cb();
        });
      },
      function(cb) {
        // query 16 photos and send them to the socket for this socket id
        req.facebook.get('/me/photos', { limit: 16 }, function(photos) {
          req.photos = photos;
          cb();
        });
      },
      function(cb) {
        // query 4 likes and send them to the socket for this socket id
        req.facebook.get('/me/likes', { limit: 4 }, function(likes) {
          req.likes = likes;
          cb();
        });
      },
      function(cb) {
        // use fql to get a list of my friends that are using this app
        req.facebook.fql('SELECT uid, name, is_app_user, pic_square FROM user WHERE uid in (SELECT uid2 FROM friend WHERE uid1 = me()) AND is_app_user = 1', function(result) {
          req.friends_using_app = result;
          cb();
        });
      }
    ], function() {
      render_page(req, res);
    });

  } else {
    render_page(req, res);
  }
}

app.get('/', handle_facebook_request);
app.post('/', handle_facebook_request);
4

2 回答 2

1

您似乎正在使用 res.render 函数,但似乎没有将它传递给 app 对象。我相信(除非我遗漏了什么)你需要将 app 对象传递给渲染函数。例如:

res.render('view_name', { app: { name: 'Site_Name' } } );

如果您在大量视图中使用应用程序,另一个选项是添加应用程序对象 app.locals,这将使其在所有视图中可用(从当前应用程序呈现)。这可以这样做:

app.locals({
    app: {
        name: 'Site_Name'
    }
});

然后您不需要将 app 传递给每个渲染调用,并且

res.render('view_name', {} );

应该管用。

于 2013-06-04T16:24:35.043 回答
1

这是 Facebook 应用程序安全性的问题,在此解决:

Heroku - 使用 Node.js 创建了一个 facebook 应用程序,它给出了类型错误

我通过在我的应用程序上禁用沙盒模式让它工作。

于 2013-09-12T12:31:09.017 回答