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

Node.js报错TypeError: Cannot read properties of undefined (reading 'apply')求助

问题描述

我是Node.js新手,查了相关错误解答没解决问题。用socket.io开发多人游戏,用Express静态托管React应用时,大厅能正常显示,但游戏启动时服务器抛出TypeError: Cannot read properties of undefined (reading 'apply')错误。前后端分端口运行时应用完全正常,请问哪里操作错了?

相关代码

api.js

const express = require('express')
const path = require('path')

const api = express.Router()

api.use(express.static(path.join(__dirname, "..", "public")))

module.exports = api 

server.js

const http = require('http')
const io = require('socket.io')

const sockets = require('./sockets')

const apiServer = require('./api')
const httpServer = http.createServer(apiServer)
const socketServer = io(httpServer, {
    cors: {
        origin: 'http://localhost:3000',
        methods: ["GET", "POST"]
    }
})


const PORT = 4000

httpServer.listen(4000, () => {
    console.log(`Server is running on port: ${PORT}`)
})

sockets.listen(socketServer)

日志信息

服务器启动及用户连接日志

Server is running on port: 4000
User connected CTmTWswPSNdfhhl2AAAB
{
  playerData: {
    pid: '53f7bfaf-bbbb-496c-a666-f55a9d574054',
    avatar: 11,
    name: 'Nyah'
  },
  players: 1
}
User connected UkfcIX202fDXJ6caAAAD
{
  playerData: {
    pid: '09b68067-cc0d-460d-b28c-21cde0c54862',
    avatar: 9,
    name: 'Walter'
  },
  players: 2
}

游戏启动时错误日志

Game on Guys!!!
/home/aimkeys/Development/projects/card-games/poker-server/node_modules/express/lib/router/index.js:646
    return fn.apply(this, arguments);
              ^

TypeError: Cannot read properties of undefined (reading 'apply')
    at Immediate.<anonymous> (/home/aimkeys/Development/projects/card-games/poker-server/node_modules/express/lib/router/index.js:646:15)
    at processImmediate (node:internal/timers:468:21)
排查与解决思路

这个错误来自Express路由内部,说明某个请求匹配到了路由,但对应的处理函数fn是undefined。结合分端口运行正常、托管后报错的现象,问题大概率出在静态托管的路由匹配逻辑和前端请求路径的变化上:

  1. 错误根源分析
    分端口时,前端在3000端口,所有请求后端的接口/Socket事件都是明确指向4000端口;但托管后前端和后端同端口,前端可能用了相对路径请求某些未定义的后端接口,Express找不到对应的处理函数,就会触发这个错误。另外,用express.Router()来托管静态文件的方式不规范,Router是用来分组API路由的,静态资源托管应该直接挂在Express实例上,避免路由匹配冲突。

  2. 具体修复步骤

    • 调整静态托管方式:把api.js改成直接创建Express实例,而不是用Router。修改后的api.js:
      const express = require('express')
      const path = require('path')
      
      const api = express()
      
      // 先定义API路由(如果有的话),再托管静态文件
      // api.use('/api', ...) 这里可以加你的API路由
      
      // 托管静态文件,确保所有静态资源请求都被处理
      api.use(express.static(path.join(__dirname, "..", "public")))
      
      module.exports = api 
      
    • 检查前端请求路径:游戏启动时打开浏览器开发者工具,查看网络请求,确认是否有请求了不存在的路径(比如/game/start这类后端没定义的路由)。如果有,要么在后端补充对应的路由处理,要么修改前端用Socket.io事件代替HTTP请求。
    • 确认Socket.io路径不冲突:确保Socket.io的默认路径/socket.io没有被Express的静态托管或其他路由覆盖,当前配置里这个应该没问题,但可以在socket.io初始化时显式指定path: '/socket.io'来确认。
  3. 验证修改
    重启服务器后测试游戏启动流程,看错误是否消失。如果还有问题,检查sockets.js里的逻辑,是否有代码误触发了HTTP请求而不是Socket事件。

内容的提问来源于stack exchange,提问作者aimkeys mwaura

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:05:27