簡體   English   中英

Express.js 無法讀取未定義的屬性“req”

[英]Express.js Cannot read property 'req' of undefined

我的 Express.js 應用程序一直在拋出Cannot read property 'req' of undefined 本質上,它偵聽GET請求,抓取content查詢,然后用表回復。 這是出現問題的部分。

索引.js

var panels = require('./modules/panels.js');
app.get('/panel', function (req, res) {
    var user;
    if (user = req.session.user) {
        panels.getContents(req.query.content, user.innId, res.send);
    } else {
        res.sendStatus(401);
    }
});

模塊/panels.js

exports.getContents = function(panelName, innId, callback) {
    var response = "";
    switch (panelName) {
        case 'tenants':
            con.query(queryString, queryParams, function(err, rows) {
                if (err) {
                    handle(err);
                } else {
                    if (rows.length == 0) {
                        var tenants = 0;
                        var debtors = 0;
                    } else {
                        var tenants = rows[0].tenants;
                        var debtors = rows[0].length;
                    }
                    response = convertToHTMLTable(rows);
                }
                callback(response); /*THE ERROR POINTS HERE */
            });
            break;

        /* other cases here */

        default:
            response += "Invalid Request";
            callback(response);
    }
}

我做錯了什么? 我的猜測是我不應該將res.send作為回調傳遞。 那么,我該如何解決呢?

我也遇到了這個錯誤,在咀嚼錯誤信息並盯着我的代碼太久之后,它點擊了。

我(和上面的提問者)有如下代碼:

  somethingAsync
  .then(res.send) // <-- storing send() divorced from parent object "res"
}

問題是當 res.send 稍后被調用時,它脫離了它的動態范圍——這意味着在send方法內部調用this ,通常指的是res ,現在指的是global 顯然,根據錯誤消息, res.send包含對this.req的引用。

一個等效的場景:

res = {
    send: function() { 
        console.log(this.originalMessage.req);
    },
    originalMessage: { req: "hello SO" },
};

res.send();
// # "hello SO"
const x = {};
x.send = res.send;
x.send();
// # Uncaught TypeError: Cannot read property 'req' of undefined

或者,換一種說法:

new Promise(_ => _())
.then(_ => console.log(this.msg.req));
// # Uncaught (in promise) TypeError: Cannot read property 'req' of undefined

兩種解決方案:

handler(req, res) {
  somethingAsync
  .then(() => res.send())
   // ^ send will be called as a method of res, preserving dynamic scope
   // that is, we're storing a function that, when called, calls
   // "res.send()", instead of storing the "send" method of "res" by itself.
}

理論上更慣用的方法是

handler(req, res) {
  somethingAsync
  .then(res.send.bind(res))
  //^ res is explicitly bound to the saved function as its dynamic scope
}

動態范圍的有害小問題,那個。 似乎 express 應該放棄動態范圍,或者至少拋出一個更好的錯誤......

index.js 中試試這個

panels.getContents(req.query.content, user.innId, res);

並進入 panel.js

exports.getContents = function(panelName, innId, response) {
    var response = "";
    switch (panelName) {
        case 'tenants':
            con.query(queryString, queryParams, function(err, rows) {
                if (err) {
                    handle(err);
                } else {
                    if (rows.length == 0) {
                        var tenants = 0;
                        var debtors = 0;
                    } else {
                        var tenants = rows[0].tenants;
                        var debtors = rows[0].length;
                    }
                    response.send(convertToHTMLTable(rows));
                }
            });
            break;

        /* other cases here */

        default:
            error += "Invalid Request";
            response.send(error)
    }
}

當您將res.send作為參數傳遞給getContents函數( panels.getContents(req.query.content, user.innId, res.send); )時,它會傳入一個新變量,您將其稱為callback

所以res.send現在從它的原始/假設是lexical context / binding中剝離,在這種情況下是res對象,並且似乎res.send使用this.req使用res對象中的req屬性。

您在這里所做的是無意中將函數sendthis值更改為全局對象。

解決方案

有兩種方法可以解決這個問題

  • panels.getContents(req.query.content, user.innId, () => res.send);

// 或者

  • panels.getContents(req.query.content, user.innId, res.send.bind(res));

在第二種解決方案中,您綁定函數res.send以始終將this任何值視為res對象( bind it to the res object

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM