You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中间件连接MongoDB失败,报bson模块未定义属性错误

问题:Next.js中间件连接MongoDB时抛出BSON相关错误

代码示例

import { getValidSubdomain } from '@/lib/getValidSubdomain';
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import * as mongoDB from 'mongodb';
let cachedDb: mongoDB.Db = null;

export function middleware(req: NextRequest) {
  const host = req.headers.get('host');
  const subdomain = getValidSubdomain(host);
  console.log({subdomain})

  if(!subdomain) return NextResponse.next()
  console.log({MONGOURL: process.env.MONGO_URL})

   mongoDB.MongoClient.connect(process.env.MONGO_URL, {
     useNewUrlParser: true,
     useUnifiedTopology: true,
   })
     .then((client) => {
       const db = client.db();
     })
  
}); // 此处存在语法错误:多余的闭合括号与分号
}

export const config = {
  matcher: '/(.*)',
}

报错信息

- error node_modules/bson/lib/bson/symbol.js (2:0) @ <unknown>
- error Cannot read properties of undefined (reading 'custom')

原因分析

Next.js中间件默认运行在Edge Runtime环境,官方mongodb驱动依赖的BSON库使用了Edge环境不支持的Node.js内置API(如Symbol.custom这类非标准扩展),导致运行时抛出未定义属性错误。同时原代码存在语法错误,多余的});会导致代码无法正常执行。

解决方案

1. 修复基础语法错误

先移除代码中多余的});,确保代码语法合法:

import { getValidSubdomain } from '@/lib/getValidSubdomain';
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import * as mongoDB from 'mongodb';

export function middleware(req: NextRequest) {
  const host = req.headers.get('host');
  const subdomain = getValidSubdomain(host);
  console.log({subdomain})

  if(!subdomain) return NextResponse.next()
  console.log({MONGOURL: process.env.MONGO_URL})

  mongoDB.MongoClient.connect(process.env.MONGO_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
    .then((client) => {
      const db = client.db();
      // 添加子域名查询逻辑,例如:
      // db.collection('subdomains').findOne({ name: subdomain })
      client.close(); // 操作完成后关闭连接,避免资源泄漏
    })
    .catch(err => {
      console.error('MongoDB连接失败:', err);
      return NextResponse.error();
    });
}

export const config = {
  matcher: '/(.*)',
}

2. 改用Edge兼容的MongoDB访问方案

若修复语法后仍报错,推荐使用以下两种适配Edge环境的方案:

  • 方案一:使用MongoDB Atlas Data API
    通过HTTP请求调用Data API,完全兼容Edge环境,无需安装官方驱动:

    export async function middleware(req: NextRequest) {
      const host = req.headers.get('host');
      const subdomain = getValidSubdomain(host);
      if(!subdomain) return NextResponse.next()
    
      try {
        const response = await fetch('https://<你的集群ID>.mongodb-data-api.mongodb-app.com/api/v1/action/findOne', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'api-key': process.env.MONGODB_DATA_API_KEY
          },
          body: JSON.stringify({
            dataSource: '<数据源名称>',
            database: '<数据库名>',
            collection: '<集合名>',
            filter: { name: subdomain }
          })
        });
        const data = await response.json();
        if(data.document) {
          // 子域名存在,继续请求流程
          return NextResponse.next();
        } else {
          // 子域名不存在,返回404或跳转
          return NextResponse.redirect(new URL('/404', req.url));
        }
      } catch(err) {
        console.error('查询子域名失败:', err);
        return NextResponse.error();
      }
    }
    
  • 方案二:使用Edge兼容驱动包
    尝试使用mongodb-edge-client这类第三方兼容包,或升级至最新版mongodb驱动(部分版本已优化Edge兼容性),需根据你的Next.js版本测试适配情况。

3. 强制使用Node.js运行时(不推荐)

若必须使用官方驱动,可强制让中间件运行在Node.js Runtime,但会丧失Edge环境的性能优势。修改next.config.js:

module.exports = {
  experimental: {
    runtime: 'nodejs', // 强制切换为Node.js运行时
  },
}

内容的提问来源于stack exchange,提问作者Arturo Verbel De León

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:52:38