我正在测试一个应用程序(希望在heroku上运行,但在本地也有问题)。当它运行http.Server.listen()时,它给我一个EACCES错误-但它只发生在一些端口上。
我在本地运行:
joe@joebuntu:~$ node
> var h = require('http').createServer();
> h.listen(900);
Error: EACCES, Permission denied
at Server._doListen (net.js:1062:5)
at net.js:1033:14
at Object.lookup (dns.js:132:45)
at Server.listen (net.js:1027:20)
at [object Context]:1:3
at Interface.<anonymous> (repl.js:150:22)
at Interface.emit (events.js:42:17)
at Interface._onLine (readline.js:132:10)
at Interface._line (readline.js:387:8)
at Interface._ttyWrite (readline.js:564:14)
我没有在端口900(或我尝试过的其他20个端口中的任何一个)上运行任何东西,因此这应该可以工作。奇怪的是,它确实在某些端口上工作。例如,端口3000可以正常工作。
是什么导致了这种情况?
更新1:
我发现在我的本地计算机上,EACCES错误出现了,因为我必须以root身份运行node才能绑定到那些特定的端口。我不知道为什么会发生这种情况,但是使用sudo可以修复它。然而,这并不能解释我如何在Heroku上修复它。没有办法在Heroku上以root身份运行,所以我怎么能在端口80上监听?
在工作站上运行
作为一般规则,没有根权限的进程不能绑定到1024以下的端口。
所以尝试一个更高的端口,或者通过sudo以更高的权限运行。在使用进程绑定到低端口后,可以降级特权。Setgid和process.setuid。
在heroku上奔跑
当你在heroku上运行你的应用程序时,你必须使用port环境变量中指定的端口。
参见http://devcenter.heroku.com/articles/node-js
const server = require('http').createServer();
const port = process.env.PORT || 3000;
server.listen(port, () => console.log(`Listening on ${port}`));
我有一个类似的问题,它拒绝在端口8080上运行,但也拒绝任何其他端口。
事实证明,这是因为环境。它读取的本地文件在变量名后面包含注释,例如:
PORT=8080 # The port the server runs at
它这样解释它,试图使用端口“8080 #服务器运行的端口”,这显然是一个无效的端口(-1)。
删除注释完全解决了这个问题。
使用Windows 10和Git Bash。
我知道这不是这里描述的问题,但它可能会帮助到一些人。我在这个问题上寻找问题的答案,所以…也许?
查看这个参考链接:
Give Safe User Permission To Use Port 80
Remember, we do NOT want to run your applications as the root user,
but there is a hitch: your safe user does not have permission to use
the default HTTP port (80). You goal is to be able to publish a
website that visitors can use by navigating to an easy to use URL like
http://ip:port/
Unfortunately, unless you sign on as root, you’ll normally have to use
a URL like http://ip:port - where port number > 1024.
A lot of people get stuck here, but the solution is easy. There a few
options but this is the one I like. Type the following commands:
sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``
Now, when you tell a Node application that you want it to run on port
80, it will not complain.