Angular+Socket.IO聊天应用部署IIS 7遇Socket.IO 404错误求助
解决Angular + Socket.IO部署到IIS 7的404问题
别急,我帮你捋捋这个问题——我之前部署Socket.IO到IIS的时候也踩过几乎一模一样的坑,咱们一步步来排查:
1. 先搞懂Socket.IO服务端的运行逻辑(这是核心!)
你本地用npm start能跑通,是因为Node.js直接启动了服务端进程,但IIS本身是静态文件服务器,不能直接运行Node.js代码。所以你不能只把server目录扔到IIS站点里就完事,得确保服务端在服务器上持续运行:
- 推荐用
PM2来管理Node进程(服务器上先装PM2:npm install pm2 -g),然后进入server目录执行pm2 start server.js(把server.js换成你的服务端入口文件名),这样服务端会后台持续运行。 - 如果你想用IIS直接管理Node服务,可以安装IISNode模块,然后在server目录里新建
web.config,配置如下:
<configuration> <system.webServer> <handlers> <add name="iisnode" path="server.js" verb="*" modules="iisnode"/> </handlers> <rewrite> <rules> <rule name="SocketIO Route"> <match url="socket.io/*" /> <action type="Rewrite" url="server.js"/> </rule> </rules> </rewrite> <iisnode loggingEnabled="true" logDirectory="iisnode"/> </system.webServer> </configuration>
2. 修正Angular客户端的Socket连接地址(你报错的直接原因!)
看你的报错信息,客户端一直在请求http://localhost:4200/socket.io/...——这是你本地开发的地址啊!部署到IIS后,客户端应该连接到IIS站点的域名/IP,而不是localhost:4200:
- 打开Angular项目里的Socket连接代码,把硬编码的地址改成相对路径:
// 原来的错误写法 this.socket = io('http://localhost:4200'); // 改成相对路径(自动适配当前站点域名) this.socket = io(); // 或者如果你的IIS站点是虚拟目录(比如/chatapp),就写: this.socket = io('/chatapp'); - 改完后重新构建Angular项目:
ng build --prod,把新生成的dist目录替换到IIS的chatapp目录下。
3. 配置IIS的URL重写与反向代理
如果你的Socket.IO服务端是独立运行在某个端口(比如3000),那得让IIS把/socket.io开头的请求转发到服务端端口:
- 先确保IIS安装了URL重写模块和Application Request Routing (ARR)(没装的话打开IIS管理器,点“管理”里的“Web平台安装程序”,搜索这两个组件安装)。
- 然后在chatapp站点的根目录(就是放dist和server的那个目录)新建
web.config,添加以下规则:
<configuration> <system.webServer> <rewrite> <rules> <!-- 先处理Angular单页路由的重写(如果你的应用有路由的话) --> <rule name="Angular Routes" stopProcessing="true"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> <add input="{REQUEST_URI}" pattern="^/(socket.io)" negate="true" /> </conditions> <action type="Rewrite" url="/chatapp/index.html" /> </rule> <!-- 转发Socket.IO请求到服务端端口 --> <rule name="SocketIO Proxy" stopProcessing="true"> <match url="socket.io/(.*)" /> <action type="Rewrite" url="http://localhost:3000/socket.io/{R:1}" /> </rule> </rules> <outboundRules> <!-- 修正Socket.IO响应里的地址,避免客户端拿到localhost:3000 --> <rule name="Rewrite SocketIO Location"> <match serverVariable="RESPONSE_Location" pattern="http://localhost:3000/(.*)" /> <action type="Rewrite" value="/chatapp/{R:1}" /> </rule> </outboundRules> </rewrite> </system.webServer> </configuration>
注意把http://localhost:3000换成你Socket.IO服务实际运行的端口。
4. 最后检查两个细节
- 权限:确保运行Node服务的用户(比如IIS_IUSRS)对server目录有读写权限,避免服务端无法启动。
- 端口占用:用
netstat -ano | findstr :3000(替换成你的服务端端口)检查端口有没有被其他程序占用,防火墙有没有开放这个端口。
验证步骤
- 先单独启动Socket.IO服务端,用
curl http://localhost:3000/socket.io测试,能返回正常响应就说明服务端没问题。 - 访问
http://你的服务器IP/chatapp/socket.io,如果能返回和上面一样的响应,说明IIS的转发生效了。 - 打开Angular应用,测试聊天功能,应该就能正常连接了。
内容的提问来源于stack exchange,提问作者nicki
相关产品推荐
相关产品推荐

