关于由Windows下pycharm远程连接和启动WSL下node执行的node项目,无法在浏览器通过localhost"port
以及 ‘ip:port’方式无法访问该服务问题
问题描述
在Windows11中使用WSL,子系统为ubuntu20.04.2,用pycharm启动WSL中的的vite项目, 运行在5173端口,在pycharm的命令行窗口已经看到服务正常在端口上运行了,但是浏览器无法通过localhost:5173
访问,也无法通过指定ubuntu的IP地址 + 端口号访问,
我首先查看了端口占用情况,该服务在WSL中正常运行,可以看到执行程序为node,但是在WSL通过curl -I
访问得到的页面是空白页面,在powershell中访问,则完全不可访问
无论是localhost : port还是curl -I localhost:port的方式都无法访问,请问可能是哪些原因造成的?如何解决呢?
时而可以通过localhost访问时而不可以,请问问题可能出现在哪里?
时而不能访问某个容器[CS架构访问数据库类型的容器],这次是不能访问vite项目,但重启有概率解决
基本信息
PS C:\Users\41999> wsl -v
WSL 版本: 1.2.5.0
内核版本: 5.15.90.1
WSLg 版本: 1.0.51
MSRDC 版本: 1.2.3770
Direct3D 版本: 1.608.2-61064218
DXCore 版本: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows 版本: 10.0.25387.1200
PS C:\Users\41999> Get-CimInstance Win32_OperatingSystem | Select-Object Caption,Version,OSArchitecture,ServicePackMajorVersion,BuildNumber
Caption : Microsoft Windows 11 专业版
Version : 10.0.25387
OSArchitecture : 64 位
ServicePackMajorVersion : 0
BuildNumber : 25387
ChatGPT给出的解决方案
出现无法通过浏览器访问和使用curl
命令访问的问题可能有几个原因:
防火墙设置:请确保Windows防火墙或其他防火墙软件没有阻止对端口5173的访问。尝试禁用防火墙或添加相应的入站规则来允许端口5173的通信。
WSL网络配置:检查WSL网络配置是否正确。确保WSL的网络设置为默认的"WSL 2 Default",并且分配了正确的IP地址。
路由配置:确认你的网络路由是否正确。尝试使用WSL的IP地址(而不是localhost)来访问服务,确保在同一网络中,并且路由设置正确。
运行在正确的WSL分发版本上:确保你的vite项目是在正确的WSL分发版本(例如Ubuntu 20.04.2)上运行,并且已经正确配置和启动。
服务绑定的IP地址和端口:在vite项目的配置中,确认服务绑定的IP地址和端口是否正确设置为0.0.0.0
和5173。
其他网络问题:检查网络连接是否稳定,确保网络正常工作。尝试使用其他网络环境(例如移动热点)来测试访问情况。
针对以上可能的原因,你可以逐一排除并尝试解决问题。另外,确保你的vite项目已经正确配置和运行,并且没有其他错误或异常。
如果问题仍然存在,请提供更多细节和错误信息,以便我能够提供更具体的帮助。
实际运行后的结论
首先分别查看5173
端口号在Ubuntu和Windows上是否被非法占用情况,前者由node占用,后者无占用
其次通过curl
分别在Windows和Linux下查看目标网页localhost:port/ip:port
,无法获取或者为空白页面
最后查看防火墙
检查主机文件的Hosts条目:在Windows主机上,打开以下文件以检查是否存在与localhost相关的条目:
C:\Windows\System32\drivers\etc\hosts
确保没有被注释掉的与"localhost"或"127.0.0.1"相关的条目。如果有注释掉的条目,请取消注释并保存文件。
尝试完成上述操作后,重新启动WSL和PyCharm,并尝试通过浏览器访问localhost:5173或使用WSL的IP地址进行访问。如果问题仍然存在,请提供任何相关的错误消息或进一步的详细信息,以便我能够提供更准确的帮助。
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
解决过程信息
该项目在pycharm
中CMD的显示情况
VITE v4.1.4 ready in 244 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h to show help
我在浏览器通过localhost:5173
以及ip:port
即172.31.158.99:5173
访问时遇到如下信息
嗯… 无法访问此页面172.31.158.99 已拒绝连接。
请尝试:
在 web 上搜索 172 31 158 99
检查连接
检查代理和防火墙
ERR_CONNECTION_REFUSED
检查 Internet 连接
请检查你的网络电缆、调制解调器和路由器。
要允许 Microsoft Edge 访问网络,请在防火墙或防病毒软件中进行 设置。
如果它已被列为允许访问网络的程序,请尝试 将其从列表中删除,然后重新添加。
如果使用代理服务器:
请检查代理设置。你可能需要向组织询问代理服务器是否正在工作。如果你认为不应该使用代理服务器,请设置 > 系统 > 打开计算机的代理设置
3. Linux下网络配置
```bash
(base) tylor@Legion:~[imath:0] ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:58ff:fec7:c366 prefixlen 64 scopeid 0x20<link>
ether 02:42:58:c7:c3:66 txqueuelen 0 (Ethernet)
RX packets 10769 bytes 9530686 (9.5 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 9037 bytes 1173445 (1.1 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.31.158.99 netmask 255.255.240.0 broadcast 172.31.159.255
inet6 fe80::215:5dff:fe66:5da9 prefixlen 64 scopeid 0x20<link>
ether 00:15:5d:66:5d:a9 txqueuelen 1000 (Ethernet)
RX packets 2292 bytes 748220 (748.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 748 bytes 58618 (58.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 以下均为docker的虚拟网卡
Windows11本机host配置
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
在Linux通过命令lsof -i:5173
查看端口号占用情况得到如下反馈
(base) tylor@Legion:~[/imath:0] lsof -i:5173
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 8680 tylor 18u IPv4 107415 0t0 TCP localhost:5173 (LISTEN)
在Windows下查看端口占用,其结果如下
PS C:\Users\41999> netstat -ano | findstr :5173
PS C:\Users\41999> netstat -ano | findstr 172.31.158.99:5173
PS C:\Users\41999> netstat -ano | findstr 127.0.0.1:5173
通过curl -I 127.0.0.1:5173
得到如下反馈
(base) tylor@Legion:~[imath:0] curl -I 127.0.0.1:5173
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: text/html
Cache-Control: no-cache
Etag: W/"1ab-IJ0xQJXEwa71YPSLIMMK+sL5iNc"
Date: Wed, 14 Jun 2023 00:29:09 GMT
Connection: keep-alive
Keep-Alive: timeout=5
使用curl -i 127.0.0.1:5173
命令,得到如下反馈,我将其黏贴并且作为HTML
文件打开时,是一个空白网页
(base) tylor@Legion:~[/imath:0] curl -i 127.0.0.1:5173
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: text/html
Cache-Control: no-cache
Etag: W/"1ab-IJ0xQJXEwa71YPSLIMMK+sL5iNc"
Date: Wed, 14 Jun 2023 00:29:34 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 427
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module" src="/@vite/client"></script>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
在Windows下通过 curl
命令获得如下反馈
PS C:\Users\41999> Invoke-WebRequest -URI 127.0.0.1:5173
Invoke-WebRequest : 无法连接到远程服务器
所在位置 行:1 字符: 1
+ Invoke-WebRequest -URI 127.0.0.1:5173
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest],WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
PS C:\Users\41999> Invoke-WebRequest -URI 172.31.158.99:5173
Invoke-WebRequest : 无法连接到远程服务器
所在位置 行:1 字符: 1
+ Invoke-WebRequest -URI 172.31.158.99:5173
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest],WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
而我通过 node
程序反向查看运行状态时,得到如下反馈
(base) tylor@Legion:~[imath:0] ps -ef | grep node
root 104 1 0 03:21 ? 00:00:00 snapfuse /var/lib/snapd/snaps/lxd_22753.snap /snap/lxd/22753 -o ro,nodev,allow_other,suid
root 105 1 0 03:21 ? 00:00:00 snapfuse /var/lib/snapd/snaps/core20_1879.snap /snap/core20/1879 -o ro,nodev,allow_other,suid
root 112 1 0 03:21 ? 00:00:00 snapfuse /var/lib/snapd/snaps/snapd_19122.snap /snap/snapd/19122 -o ro,nodev,allow_other,suid
root 113 1 0 03:21 ? 00:00:04 snapfuse /var/lib/snapd/snaps/snapd_19361.snap /snap/snapd/19361 -o ro,nodev,allow_other,suid
root 114 1 0 03:21 ? 00:00:00 snapfuse /var/lib/snapd/snaps/core20_1891.snap /snap/core20/1891 -o ro,nodev,allow_other,suid
root 115 1 0 03:21 ? 00:00:00 snapfuse /var/lib/snapd/snaps/lxd_24061.snap /snap/lxd/24061 -o ro,nodev,allow_other,suid
tylor 1121 1066 1 03:21 ? 00:03:45 /usr/share/kibana/bin/../node/bin/node /usr/share/kibana/bin/../src/cli/dist --ops.cGroupOverrides.cpuPath=/ --ops.cGroupOverrides.cpuAcctPath=/
tylor 12369 12367 0 09:11 pts/0 00:00:00 /bin/sh -c export PATH="/opt/node-v18.16.0-linux-x64/bin:[/imath:0]PATH" && cd /home/tylor/floatlight/floatlightweb && /opt/node-v18.16.0-linux-x64/bin/yarn run dev
tylor 12370 12369 0 09:11 pts/0 00:00:00 node /opt/node-v18.16.0-linux-x64/bin/yarn run dev
tylor 12382 12381 0 09:11 pts/0 00:00:00 /opt/node-v18.16.0-linux-x64/bin/node /home/tylor/floatlight/floatlightweb/node_modules/.bin/vite
tylor 12393 12382 0 09:11 pts/0 00:00:00 /home/tylor/floatlight/floatlightweb/node_modules/@esbuild/linux-x64/bin/esbuild --service=0.16.17 --ping
tylor 12642 12597 0 09:18 pts/7 00:00:00 grep --color=auto node
WSL下防火墙已关闭
(base) tylor@Legion:~$ sudo ufw status
[sudo] password for tylor:
Status: inactive
xxxx
补充信息
如果我们将某个项目启动的服务放置在0.0.0.0
这个IP上,有什么好处呢?
将某个项目启动的服务放置在0.0.0.0
这个IP上,可以让该服务绑定到所有可用的网络接口上,包括本地连接和远程连接,而不是只绑定到一个特定的IP地址上。这样做的好处有以下几点:
可以让本地和远程的客户端都可以访问该服务,方便进行开发和测试。
可以避免IP地址冲突的问题,因为服务不会只绑定到一个特定的IP地址上。
可以增强服务的可用性和负载均衡能力,因为服务可以在多个网络接口上同时运行。
需要注意的是,将服务绑定到0.0.0.0
这个IP上可能会带来一些安全风险,因为它可以让任何人都可以访问该服务。因此,在生产环境中,我们应该仅将服务绑定到特定的IP地址上,以增强安全性。
解决方案
由徐晓峰老师提供
在vite项目配置文件package.json中,将内容修改为
{
"scripts": {
"dev": "vite --host --port 5173",
},
}
原来的配置为
{
"scripts": {
"dev": "vite",
},
}
出错的原因
浏览器通过 IP(WSL): Port
无法访问,是因为localhost与 127.0.0.1
无映射关系,提供页面渲染服务的vite项目监听了localhost主机名而非127.0.0.1,改变vite的配置项之后,使得项目直接监听了127.0.0.1
,而我取消了注释,使得二者可以正常映射,配置文件的路径为Windows的配置C:\Windows\System32\drivers\etc\hosts
。同时保持前端和后端项目除了端口号不同以外,均在127.0.0.1
这个IP地址上,再结合跨域即可解决。
访问前端页面,主页无法加载两个组件header && bottom的文字信息,banner 组件的静态图片信息的原因:前后端监听的端口不在同一个IP,以IP(WSL): Port
访问前端时,前端用axios代理请求去获取API接口,跨域的豁免名单无此IP地址,且Redis缓存配置的路径仍然是127.0.0.1
,主要是跨域行为被阻止,导致无法获取静态资源。
关于访问逻辑:浏览器地址栏输入IP(WSL): Port
或者 127.0.0.1: Port
,访问前端资源时,前端原来配置的项目监听地址为http://localhost:5173/
, localhost 与 127.0.0.1
无映射关系,自然不可以访问。按照正常的逻辑,项目部署在WSL,端口监听时,对localhost/127.0.0.1的访问是映射给WSL的IP地址172.31.158.99
![](C:\Users\41999\Desktop\LeetCode\Bilibili\wsl.assets\项目结构说明.png)
特别鸣谢
- 感谢徐晓伟老师的指导,分别给出指定IP和
0.0.0.0
不安全但内外部IP均可访问的方式
- 感谢诸位群友帮忙联合调试,并且解释原理,和跳出问题本身给出解决人的问题的方法
- 群友0x1234,Leo025, Debin 平替建议, hyper-v + WSL内自定义网卡, VirtualBox
- 群友 HarsheXF 宿主机与WSL网络隔离
- 蓝胖子头像群友补充:host.docker.internal
- 群友0x1234的提问让我明白,在展示IDE和浏览器联调的时候,应当给出明确的项目整体结构信息 和 前后端访问链路和逻辑,才能更好理解调试过程
额外的信息
如何增强解决此类项目网络通信的问题的能力?
(布莱克士多)你可能缺操作系统原理和计算机网络基础,要不考虑找个考研视频先看看
培训班是不会教你这些的
所以我最后想问大家一个问题,就是怎么来提升对项目的理解呢?感觉我还是处于一种CV代码的水平,虽然偶尔为了解决问题会逐步调试?
(椰奶肥羊 小甘雨)或者可以从不依赖视频讲解,自己尝试读懂一个项目做起,没有别人的指导,自己来想,理解的深度是不一样的。可能也许只是一个bot,或者只是一个web应用,或者一个简单的存储引擎,先找个觉得还行的,抄一下,有个大概的印象。这种东西本来就不是一蹴而就的
参考
- Microsoft doc:使用 WSL 访问网络应用程序
https://learn.microsoft.com/zh-cn/windows/wsl/networking#accessing-a-wsl-2-distribution-from-your-local-area-network-lan
- xxx