“未定义不是函数”在nodejs/expressjs中

发布于 2024-12-03 17:23:53 字数 2228 浏览 5 评论 0原文

我正在使用“express-namespace”对我的路由进行分类。 这是我的代码。

..
 9 var controllers = require('./controllers');
 10 require('express-namespace');
..
 46
 47 app.namespace('/json', function(){
 48     app.post('/', function(req, res, next){
 49         res.header('Content-Type', 'application/json');
 50         next();
 51     });
 52     /**
 53      * Map the controller objects and its actions
 54      * to the corresponding URL in lower case
 55      */
 56     for(var controller in controllers){
 57         app.namespace('/' + controller.toLowerCase(), function(){
 58             controller = controllers[controller];
 59             for(var action in controller){
 60                 app.post('/' + action.toLowerCase(), function(req,res){
 61                     action = controller[action];
 62                     action(req, function(result){
 63                         res.send(result);
 64                     });
 65                 });
 66             }
 67         });
 68     }
 69 });

这是我的 ./controllers.js 代码:

...
 4 var Users = {
 5 };
 6
 7 Users.create = function(req, result){
...
 22 }
 23
 24 exports.Users = Users;
 25

我的观点是将我的控制器代码移动到单个 .js 文件中并映射 我的所有控制器都变成相应的小写 URL,所以我的应用程序是 相当整洁。

每次我运行“node”时,这对于第一个 POST 来说效果非常好 应用程序.js'。 如果我第二次POST到该URL,出现以下异常 发生:

TypeError: undefined is not a function
   at CALL_NON_FUNCTION (native)
   at /home/carl/source/node/funner/app.js:62:21
   at callbacks (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:272:11)
   at param (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:246:11)
   at pass (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:253:5)
   at Router._dispatch (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:280:4)
   at Object.handle (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:45:10)
   at next (/usr/local/lib/node/.npm/connect/1.7.0/package/lib/http.js:201:15)
   at /usr/local/lib/node/.npm/connect/1.7.0/package/lib/middleware/session.js:323:9
   at /usr/local/lib/node/.npm/connect/1.7.0/package/lib/middleware/session.js:342:9

任何人都可以在这里给我提示吗?

I'm using 'express-namespace' to categorize my routing.
Here is my code.

..
 9 var controllers = require('./controllers');
 10 require('express-namespace');
..
 46
 47 app.namespace('/json', function(){
 48     app.post('/', function(req, res, next){
 49         res.header('Content-Type', 'application/json');
 50         next();
 51     });
 52     /**
 53      * Map the controller objects and its actions
 54      * to the corresponding URL in lower case
 55      */
 56     for(var controller in controllers){
 57         app.namespace('/' + controller.toLowerCase(), function(){
 58             controller = controllers[controller];
 59             for(var action in controller){
 60                 app.post('/' + action.toLowerCase(), function(req,res){
 61                     action = controller[action];
 62                     action(req, function(result){
 63                         res.send(result);
 64                     });
 65                 });
 66             }
 67         });
 68     }
 69 });

and here is my ./controllers.js code:

...
 4 var Users = {
 5 };
 6
 7 Users.create = function(req, result){
...
 22 }
 23
 24 exports.Users = Users;
 25

My point is to move my controllers code into a single .js file and map
all my controllers into corresponding lower-case URL so my app is
pretty neat.

This works out pretty good for the first POST every time I run 'node
app.js'.
If I POST to the URL for the second time, the following exception
occurs:

TypeError: undefined is not a function
   at CALL_NON_FUNCTION (native)
   at /home/carl/source/node/funner/app.js:62:21
   at callbacks (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:272:11)
   at param (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:246:11)
   at pass (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:253:5)
   at Router._dispatch (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:280:4)
   at Object.handle (/usr/local/lib/node/.npm/express/2.4.6/package/lib/router/index.js:45:10)
   at next (/usr/local/lib/node/.npm/connect/1.7.0/package/lib/http.js:201:15)
   at /usr/local/lib/node/.npm/connect/1.7.0/package/lib/middleware/session.js:323:9
   at /usr/local/lib/node/.npm/connect/1.7.0/package/lib/middleware/session.js:342:9

Can anyone give me a hint here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

人间☆小暴躁 2024-12-10 17:23:53

我没有看到明显的错误,但我确实看到了一些危险的 JavaScript。 for( key in obj ) 语句应通过 hasOwnProperty ifs 进行过滤,并且使用 var 语句来确定循环内函数中局部变量的范围非常重要。

 47 app.namespace('/json', function(){
 48     app.post('/', function(req, res, next){
 49         res.header('Content-Type', 'application/json');
 50         next();
 51     });
 52     /**
 53      * Map the controller objects and its actions
 54      * to the corresponding URL in lower case
 55      */
 56     for(var controller in controllers){
            **if(controller.hasOwnProperty(controller) {**
 57         app.namespace('/' + controller.toLowerCase(), function(){
 58             **var mycontroller** = controllers[controller];
 59             for(var action in mycontroller){
                    **if(mycontroller.hasOwnProperty(action) {**
 60                 app.post('/' + action.toLowerCase(), function(req,res){
 61                     **var myaction** = mycontroller[action];
 62                     myaction(req, function(result){
 63                         res.send(result);
 64                     });
 65                 });
                    }
 66             }
 67         });
            }
 68     }
 69 });

I don't see a clear error, but I do see some dangerous javascript. for( key in obj ) statements should be filtered by hasOwnProperty ifs and it's important to use var statements to scope local variables in functions within loops.

 47 app.namespace('/json', function(){
 48     app.post('/', function(req, res, next){
 49         res.header('Content-Type', 'application/json');
 50         next();
 51     });
 52     /**
 53      * Map the controller objects and its actions
 54      * to the corresponding URL in lower case
 55      */
 56     for(var controller in controllers){
            **if(controller.hasOwnProperty(controller) {**
 57         app.namespace('/' + controller.toLowerCase(), function(){
 58             **var mycontroller** = controllers[controller];
 59             for(var action in mycontroller){
                    **if(mycontroller.hasOwnProperty(action) {**
 60                 app.post('/' + action.toLowerCase(), function(req,res){
 61                     **var myaction** = mycontroller[action];
 62                     myaction(req, function(result){
 63                         res.send(result);
 64                     });
 65                 });
                    }
 66             }
 67         });
            }
 68     }
 69 });
喜爱纠缠 2024-12-10 17:23:53

我没有使用 express-namespace 但我认为您可以使用 req.params 映射控制器的 URL。像这样:

app.namespace('/json', function(){

  app.post('/:controller/:action', function(req, res, next){

    var controller = req.params.controller,
            action = req.params.action;

        controller[0] = controller[0].toUpperCase();

    if( controllers[ controller ][ action ] ){
      res.header('Content-Type', 'application/json');

      controllers[ controller ][ action ](req, function(result){
        res.send(result);
      });

    }
    else
      res.send('Action %s is not defined for the %s controller', action, controller);    


  });

});

对于 app.post('/:controller', ...); 也可以这样做,

告诉我它是否有效。

PD。我是 node+express 的新手。

I haven't used express-namespace but I think you can just map the urls for the controllers as they come using req.params. Like so:

app.namespace('/json', function(){

  app.post('/:controller/:action', function(req, res, next){

    var controller = req.params.controller,
            action = req.params.action;

        controller[0] = controller[0].toUpperCase();

    if( controllers[ controller ][ action ] ){
      res.header('Content-Type', 'application/json');

      controllers[ controller ][ action ](req, function(result){
        res.send(result);
      });

    }
    else
      res.send('Action %s is not defined for the %s controller', action, controller);    


  });

});

And the same can be done for app.post('/:controller', ...);

Tell me if it works.

PD. I'm new to node+express.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文