使用Express提供网页时,使用`path.join`节点JS TypeError

时间:2013-03-21 20:31:29

标签: linux node.js express socket.io

我刚刚在运行Linux Peppermint Three的上网本上安装了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重新安装它。我查找了错误(通过搜索上面的第一行)并找到提及herehere以及here,其中所有人似乎都在说它已经解决了。

任何想法我还能尝试让我的简单页面服务器工作吗?

3 个答案:

答案 0 :(得分:13)

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

以下是来自连接

的有问题的代码
  // 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; DR

您可以在此期间修补代码以解决问题。

绝对路径

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

相对路径

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

设置{root: ''}将无法在静态中间件中进行真正的测试。

答案 1 :(得分:4)

问题似乎与新版本的Node不兼容。我不得不将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必须侦听在Express调用周围创建的server(即,不像以前那样app);这解决了在客户端启动Socket.IO脚本的一些问题。在撰写本文时,我仍然don't fully understand how the script is accessed given where the page is being served from。当我知道更多时,我会尝试回来更新。

PS。我很感激@robertklep指导我完成了这一点,你可以在上面的评论中看到。谢谢!

答案 2 :(得分:0)

快速修复

sed -i bak -e  's/\/\/.join/if(root\ ==\ null){root="";}\/\//g' node_modules/express/node_modules/connect/lib/middleware/static.js