我最近从 Linux 切换到 Windows 10 上的 WSL2(Ubuntu 20.04)。当我运行任何 NodeJs 应用程序或 Apache 或 Nginx 等服务器时,一切在 localhost 或 127.0.0.1 上运行正常,但当我使用本地 IP 地址(192.168.1.65)时不起作用。
运行 node js 应用程序时 netstat -tupln
我曾尝试关闭 Windows 和 WSL 中的防火墙,但没有效果。
我从“程序和功能”启用了 IIS,它似乎在 localhost 和 ip 上运行良好。因此,我认为这不是网络问题。
我读过的所有帖子都表明,如果可以通过 127.0.0.1 访问该站点,而不是通过 ip 访问,那么您可以为 Apache 或 Nginx 配置服务器配置文件。但我重新安装了 wsl,并且仅通过 NodeJs/Express 托管。
express 应用程序的 server.js 代码是:
const express = require("express");
const next = require("next");
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = express();
server.use(express.static("public"));
server.all("*", (req, res) => {
return handle(req, res);
});
server.listen(port, "0.0.0.0", (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
});
我要做的就是在同一网络上通过手机访问该网站。
答案1
这里的核心问题是 WSL2 在具有自己的虚拟 NIC 的 Hyper-V VM 中运行,在 Windows 主机后面运行 NAT。另一方面,WSL1 与 Windows NIC 桥接运行。
在 上localhost
,Windows 似乎确实进行了自动映射,但对于主机 IP 地址(以及因此在本地网络上),它却没有。
你会在这个网站上找到很多关于这个特定主题的信息Github 线程,以及一些解决方法:
选项 1:WSL1
首先,也是最简单的方法,就是如果可以的话,针对这个特定的应用程序使用 WSL1。您可以通过执行(从 PowerShell)a或使用 a然后wsl --set-version <distroname> 1
克隆现有实例,将 WSL2 实例转换为 WSL1 。我更喜欢克隆,因为它可以为您提供备份。wsl --export <distroname> <archivename>.tar
wsl --import <distroname> <installlocation) <archivename>.tar
选项 2:使用 Windows 端口转发netsh
netsh
在 Windows 下使用per进行端口转发此评论在该线程上。请注意,WSL2 实例的虚拟 NIC 在每次重新启动时都会获得一个新地址,因此您必须netsh
在每次重新启动时重复该命令,或者按照所述在脚本中设置它,并通过任务管理器将其设置为在每次启动时运行。另请注意,您需要修改 Windows 防火墙规则。
选项 3:通过 WSL1 进行端口转发socat
- 在 WSL2 实例旁边设置一个基本的 WSL1 实例
- 安装
socat
在两者上 - 从 WSL1 实例运行
socat -d -d TCP-LISTEN:3000,reuseaddr,fork EXEC:'wsl.exe -d <WSL2DistroName> "socat -d -d TCP-CONNECT:127.0.0.1:3000 -"'
,确保用正确的名称(不带括号)替换。
这基本上会将 WSL1 上端口 3000 上的任何内容转发到 WSL2 上的 3000,并且由于 WSL1 无论如何都是“桥接”运行,因此与 Windows 主机上端口 3000 的连接也将通过该路由。
netsh
与无需担心 WSL2 IP 在每次启动时发生变化的选项相比,这具有优势,因为它通过wsl.exe
命令的标准输出工作。
选项 4:桥接模式
如果您使用的是 Windows 10 Pro 或更高版本,该线程中提供了有关如何在桥接模式下运行 WSL2 NIC 的说明。我从未采用过这种方式,因为我已经能够使用其他三种方法。