Nodejs TypeError: Cannot call method 'findOne' of null

Nodejs TypeError: Cannot call method ‘findOne’ of null

Node.js 开发指南上的例子, 我刚按照 http://cnodejs.org/topic/5141cf5e069911196d581966 上将

var MongoStore = require(‘connect-mongo’);

改成了

var MongoStore = require(‘connect-mongodb’);

运行 node app.js 显示在监听3000端口,正常

但是当启动浏览器键入 localhost:3000时, 就出现了这样的错误:

Express 500 TypeError: Cannot call method ‘findOne’ of null at MongoStore.MONGOSTORE.get (/Users/zhangnaixiao/Cold/node/NodeGuide/Chapter05/MicroBlog/node_modules/connect-mongodb/lib/connect-mongodb.js:115:15) at Object.session [as handle] (/Users/zhangnaixiao/Cold/node/NodeGuide/Chapter05/MicroBlog/node_modules/express/node_modules/connect/lib/middleware/session.js:311:11) at next

请问这是什么原因呢? 该怎么解决?


7 回复

根据你描述的错误信息,TypeError: Cannot call method 'findOne' of null 表明在尝试调用 findOne 方法时,对象为 null。这通常发生在 MongoDB 连接失败或者配置不正确的情况下。

可能的原因

  1. MongoDB 配置错误:数据库连接字符串可能不正确。
  2. MongoDB 服务未启动:确保 MongoDB 服务已经启动。
  3. 依赖库版本问题connect-mongodbmongodb 的版本可能不兼容。

示例代码及解决方案

假设你的应用使用了 Express 和 connect-mongodb 来处理会话存储。我们来检查并修复这个问题。

正确的依赖安装

首先,确保你已经安装了正确的依赖包:

npm install express connect-mongodb mongodb

检查 MongoDB 连接配置

确保你的 MongoDB 连接配置是正确的。例如,在你的 app.js 文件中,应该有类似如下的配置:

const express = require('express');
const session = require('express-session');
const MongoStore = require('connect-mongodb');

const app = express();

// MongoDB 配置
const mongoUrl = 'mongodb://localhost:27017/mydatabase'; // 确保你的 MongoDB 服务运行在本地默认端口

app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true,
    store: new MongoStore({ url: mongoUrl })
}));

app.get('/', (req, res) => {
    req.session.views = (req.session.views || 0) + 1;
    res.send(`You have viewed this page ${req.session.views} times.`);
});

app.listen(3000, () => {
    console.log('App listening on port 3000!');
});

检查 MongoDB 服务

确保 MongoDB 服务正在运行。你可以通过以下命令启动 MongoDB 服务(如果你使用的是 macOS 或 Linux):

mongod --dbpath /data/db

或者在 Windows 上,确保 MongoDB 服务已启动。

检查日志

如果问题仍然存在,检查 MongoDB 的日志文件,以查看是否有任何连接错误或其他问题。

总结

通过以上步骤,你应该能够解决 TypeError: Cannot call method 'findOne' of null 的问题。确保 MongoDB 服务运行正常,并且配置正确。如果问题依然存在,请检查 MongoDB 日志以获取更多详细信息。


没有找到findOne模块,看看数据库中间件调用的对不对

app.use(express.session({
    secret: settings.cookieSecret,
    store: new MongoStore({
        db: settings.db
    })
}));

是指这段么?

不是没有找到findOne模块。出错信息的字面意思是"无法从null中调用findOne方法"。 可能的原因是,在初始化connect-mongodb的时候缺少某个参数(数据库连接),而这个参数对象需要有findOne方法。

有NPM上的信息可知,connect-mongodb这个模块最后一次更新是两年前了,对于发展中的Node.js而言,两年的变化是很大的,可能该模块所依赖的mongodb模块的API有所变动,才导致这个错误。

建议还是用connect-mongo

是的,查看了一下文档,conncet-mongo 是比较新的,用法是

var MongoStore = require(‘connect-mongo’)(express);

根据你的描述,错误 TypeError: Cannot call method 'findOne' of null 表明在调用 findOne 方法之前,变量可能为 null。通常情况下,这表示你在尝试访问数据库连接或存储实例,但该实例没有正确初始化。

以下是一些可能的原因及解决方案:

可能的原因

  1. 数据库连接未正确配置:确保你的数据库配置正确,并且数据库服务正在运行。
  2. 库版本不匹配:你提到从 connect-mongo 改为 connect-mongodb,两个库的API可能不同。确保你使用的是正确的库和文档。
  3. 初始化问题:可能是 MongoStore 实例未被正确初始化。

解决方案

示例代码

假设你正在使用 Express 和 connect-mongodb 库,以下是一个基本的示例,展示如何正确配置和初始化:

const express = require('express');
const session = require('express-session');
const MongoStore = require('connect-mongodb-session')(session);

// 创建数据库连接
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });

// 创建一个session存储
const store = new MongoStore({
    uri: 'mongodb://localhost:27017/mydatabase',
    collection: 'mySessions'
});

const app = express();

app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: false,
    store: store
}));

app.get('/', (req, res) => {
    req.session.username = 'exampleUser';
    res.send(`Hello ${req.session.username}`);
});

app.listen(3000, () => console.log('App is running on port 3000'));

关键点

  • 确保数据库服务运行:在本地运行 mongod 确保 MongoDB 服务正在运行。
  • 检查URI和数据库名称:确保你的数据库URI和数据库名称正确。
  • 初始化存储:确保 MongoStore 正确初始化,并且传入了正确的配置参数。

通过以上步骤,你应该能够解决 TypeError: Cannot call method 'findOne' of null 的错误。

回到顶部