7

我刚刚在运行 Linux Peppermint 3 的上网本上安装了 Node JS (v0.10.0)。我有一个文件要运行,顶部有以下内容:

var app = require('express').createServer(),
    io = require('socket.io').listen(app);

app.listen(8080);

// routing
app.get('/', function (req, res) {
  res.sendfile(__dirname + '/index.html');
});

问题是,当我访问时,localhost:8080我得到以下信息:

TypeError: Arguments to path.join must be strings
    at path.js:360:15
    at Array.filter (native)
    at exports.join (path.js:358:36)
    at exports.send (/home/guy/Dropbox/Node/socket_io echo test/node_modules/express/node_modules/connect/lib/middleware/static.js:129:20)
    at ServerResponse.res.sendfile (/home/guy/Dropbox/Node/socket_io echo test/node_modules/express/lib/response.js:186:3)
    at usernames (/home/guy/Dropbox/Node/socket_io echo test/med.js:11:7)
    at callbacks (/home/guy/Dropbox/Node/socket_io echo test/node_modules/express/lib/router/index.js:272:11)
    at param (/home/guy/Dropbox/Node/socket_io echo test/node_modules/express/lib/router/index.js:246:11)
    at pass (/home/guy/Dropbox/Node/socket_io echo test/node_modules/express/lib/router/index.js:253:5)
    at Router._dispatch (/home/guy/Dropbox/Node/socket_io echo test/node_modules/express/lib/router/index.js:280:5)

完全相同的文件适用于我的 Windows XP 笔记本电脑,但我还没有更新 Node(仍在运行 v0.8.15)。所以我不知道是我在 Linux 上安装 Node (我是新手)的问题还是版本之间的差异。显然,如果它会导致同样的问题,我不想在 Windows 上更新 Node。

我已经检查过 Express 应该在哪里,这似乎还可以。我尝试通过 npm 重新安装它。我查看了错误(通过搜索上面的第一行)并发现提到hereherehere,似乎都在说它已解决。

有什么想法(如果有的话)我可以尝试让我的简单页面服务器正常工作吗?

4

3 回答 3

13

我在节点 v0.10.2 上也遇到过这种情况,同时尝试从 0.6.14 升级。问题在于连接静态中间件,以及它如何处理路径以及 path.join 如何处理其参数的可能回归。

这是来自连接的有问题的代码

  // setup
  var maxAge = options.maxAge || 0
    , ranges = req.headers.range
    , head = 'HEAD' == req.method
    , get = 'GET' == req.method
    , root = options.root ? normalize(options.root) : null //<!-- should be ''
    , redirect = false === options.redirect ? false : true
    , getOnly = options.getOnly
    , fn = options.callback
    , hidden = options.hidden
    , done;

后来在加入路径的时候,你最终得到一个null,导致v0.10.2下的错误

  // join / normalize from optional root dir
  path = normalize(join(root, path));

在节点 0.8.21 下,你会得到这个

> require('path').join(null, 'file.txt');
'file.txt'

在节点 0.10.2 下,你会得到这个

> require('path').join(null, 'file.txt');
TypeError: Arguments to path.join must be strings
    at path.js:360:15
    at Array.filter (native)
    at Object.exports.join (path.js:358:36)
    at repl:1:17
    at REPLServer.self.eval (repl.js:110:21)
    at repl.js:249:20
    at REPLServer.self.eval (repl.js:122:7)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)

TL;博士

您可以同时修补您的代码以解决此问题。

绝对路径

var filepath = '/some/absolute/path/to/file.ext';
res.sendfile(path.basename(filepath), {root: path.dirname(filepath)}); 

或者

相对路径

res.sendfile('file.ext', {root: __dirname})

设置{root: ''}将无法通过静态中间件中的真实测试。

于 2013-04-03T17:33:43.523 回答
5

问题似乎是与新版本的 Node.js 不兼容。我必须将 Express 更新到 v3.1.0,将 Socket.IO 更新到 v9.1.13。然后,我还必须将 Windows 笔记本电脑上的 NodeJS 更新到安装在我的 Linux 上网本 v0.10.1 上的最新版本。

随着两台计算机上的所有内容都是最新的,代码(如上所述)然后需要更改为以下内容:

var app = require('express')(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server);

server.listen(8080);

// routing
app.get('/', function (req, res) {
    res.sendfile(__dirname + '/index.html');
});

注意这里直接调用 Express 模块,而不是之前使用的方法调用。另请注意,IO 必须侦听server围绕 Express 调用创建的(即,不像app我以前那样);这解决了让 Socket.IO 脚本在客户端启动的一些问题。在撰写本文时,我仍然不完全了解如何访问脚本,因为页面是从哪里提供的。当我知道更多时,我会尝试回来更新。

PS。我很感谢@robertklep,他指导我完成了这件事,正如您可能在上面的评论中看到的那样。谢谢!

于 2013-03-24T18:44:00.317 回答
0

快速解决

sed -i bak -e  's/\/\/.join/if(root\ ==\ null){root="";}\/\//g' node_modules/express/node_modules/connect/lib/middleware/static.js
于 2013-12-14T14:31:08.763 回答