难以理解的node.js http抛出连接ECONNREFUSED(IPv6?)

Bri*_*unt 5 ipv6 node.js node.js-connect

我运行node.js如下:

> http = require('http')
> http.get('http://myhost.local:8080',
    function (res) { console.log("RES" + res) }
  ).on('error', function (e) { console.log("Error:", e) })

> uri = require('url').parse("http://myhost.local:8080")
{ protocol: 'http:',
  slashes: true,
  auth: null,
  host: 'myhost.local:8080',
  port: '8080',
  hostname: 'myhost.local',
  hash: null,
  search: null,
  query: null,
  pathname: '/',
  path: '/',
  href: 'http://myhost.local:8080/' }
> http.get(uri,
    function (res) { console.log("RES" + res) }
  ).on('error', function (e) { console.log("Error:", e) })
Run Code Online (Sandbox Code Playgroud)

隐式和显式解析的URI都会引发错误,我得到以下两个输出:

错误:{[错误:连接ECONNREFUSED]代码:'ECONNREFUSED',错误号:'ECONNREFUSED',系统调用:'connect'}

主机myhost.locallocalhostin 的别名/etc/hosts,是:

127.0.0.1   localhost myhost.local myhost
255.255.255.255 broadcasthost
::1             localhost myhost.local myhost
fe80::1%lo0 localhost myhost.local myhost
Run Code Online (Sandbox Code Playgroud)

编辑:我几乎尝试了hosts文件的每个排列,包括最明显的:

127.0.0.1   localhost 
255.255.255.255 broadcasthost
::1             localhost myhost.local myhost
fe80::1%lo0 localhost
Run Code Online (Sandbox Code Playgroud)

编辑我还应该提一下,我现在已在多台Mac上试过这个.

虽然这似乎是一个相当常见的错误,但我没有看到任何有用的解释或解决方法.以下是一些值得注意的相关事实:

  1. 运行$ wget http://myhost.local:8080按预期工作,因此它不是防火墙问题.
  2. 运行$ telnet myhost.local 8080然后手动GET'ing网址工作正常,所以这不是一个奇怪的HTTP问题.
  3. 我可以毫不费力地使用node.js连接到其他主机,例如http://www.google.com

我希望有用的系统信息包括:

$ node -v
v0.9.11

$ uname -a
Darwin myhost.local 12.2.1 Darwin Kernel Version 12.2.1:
Thu Oct 18 12:13:47 PDT 2012; root:xnu-2050.20.9~1/RELEASE_X86_64 x86_64

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.8.2
BuildVersion:   12C3104

$ sudo  netstat -nalt | grep LISTEN | grep 8080
tcp6       0      0  ::1.8080  *.*    LISTEN
Run Code Online (Sandbox Code Playgroud)

有没有人知道这里发生了什么,修复可能是什么?

ale*_*lex 10

我打算在这里发布,以防其他人有问题.

Bert Belder,Node.js邮件列表:

在您的系统上,"myhost.local"解析为三个不同的地址(127.0.0.1,:: 1和fe80 :: 1).Node优先选择ipv4而不是ipv6,因此它会尝试连接到127.0.0.1.在127.0.0.1:8080上没有任何内容正在侦听,因此connect()系统调用因ECONNREFUSED而失败.节点不会使用任何其他已解析的IP重试 - 它只会向您报告错误.一个简单的解决方案是将'localhost'替换为预期的目标IP地址':: 1'.

这种行为是否正确对辩论有些开放,但这就是导致它的原因.

伯特