Blazor Server在Apache反向代理子目录下WebSocket无法连接问题
Blazor Server计数器Demo在Apache反向代理子目录下的WebSocket连接问题
问题场景
- 容器化部署(Docker)的标准Visual Studio Blazor Server计数器Demo
- 运行环境为Debian 12系统
- 通过Apache反向代理的虚拟子目录
/sd/对外提供访问
当前状态
- 直接访问容器端口
http://myserver.example.local:8082/时,WebSocket连接正常建立,应用运行无异常 - 配置Apache反向代理后,可通过
http://myserver.example.local/sd/访问应用,计数器功能可用,但WebSocket无法建立连接,应用退化为长轮询模式——每次点击"Click Me"都会新增GET请求
当前Apache站点配置
<VirtualHost *:80> DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined RewriteEngine On <Location /sd/> RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^/?(.*) "ws://127.0.0.1:8082/?$1" [P,L] ProxyPreserveHost On ProxyPass http://127.0.0.1:8082/ ProxyPassReverse http://127.0.0.1:8082/ ProxyHTMLURLMap http://127.0.0.1:8082 /sd/ ProxyHTMLURLMap / /sd/ SetOutputFilter proxy-html </Location> </VirtualHost>
注:已尝试配置app.UsePathBase()和_Host.cshtml中的<base>标签,但未解决WebSocket连接问题。
解决方案
1. 修正Apache的WebSocket重写规则
当前RewriteRule的路径映射逻辑错误,无法正确传递Blazor Server的WebSocket端点/_blazor路径。修改为以下规则:
RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^/sd/(.*) ws://127.0.0.1:8082/$1 [P,L]
2. 配置Blazor应用的路径基
在Program.cs中添加路径基配置,让应用明确自身运行在子目录下:
var builder = WebApplication.CreateBuilder(args); // 保留原有服务配置代码... var app = builder.Build(); // 添加路径基配置 app.UsePathBase("/sd"); // 保留原有中间件配置代码... app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); app.Run();
3. 修正_Host.cshtml中的base标签
确保_Host.cshtml里的base标签指向正确的子目录:
<base href="/sd/" />
4. 调整Apache的ProxyPass和ProxyPassReverse
修正路径映射逻辑,避免子目录与容器根路径混淆:
ProxyPass /sd/ http://127.0.0.1:8082/sd/ ProxyPassReverse /sd/ http://127.0.0.1:8082/sd/
同时移除ProxyHTMLURLMap和SetOutputFilter proxy-html配置——路径问题已通过应用端的UsePathBase和base标签处理,无需再用proxy-html过滤。
最终完整Apache配置
<VirtualHost *:80> DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined RewriteEngine On <Location /sd/> # WebSocket重写规则 RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^/sd/(.*) ws://127.0.0.1:8082/$1 [P,L] ProxyPreserveHost On ProxyPass http://127.0.0.1:8082/sd/ ProxyPassReverse http://127.0.0.1:8082/sd/ </Location> </VirtualHost>
验证步骤
- 重启Apache服务:
sudo systemctl restart apache2 - 重启Blazor容器,确保应用端配置生效
- 访问
http://myserver.example.local/sd/,打开浏览器开发者工具的网络面板,检查是否存在状态为"Open"的wss://myserver.example.local/sd/_blazorWebSocket连接
内容的提问来源于stack exchange,提问作者Klaus P.
相关产品推荐
相关产品推荐

