apache - “位置 0 处 JSON 中的意外令牌 H”SignalR Core 和 Apache Web 服务器上的 Kestrel
问题描述
我目前正在 Ubuntu 上运行 apache2 网络服务器。此 Web 服务器托管 Vue.js Web 应用程序,该应用程序使用 SignalR 连接到 .Net Core 应用程序(也在同一 linux 服务器上)以创建 websocket。
.Net Core 应用程序使用 Kestrel 运行。以下是将 domain.com/api 重新路由到在端口 5000 上运行的 .Net Core 应用程序的 apache 配置。
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
<VirtualHost _default_:443>
DocumentRoot /var/www/example.com/dist/spa
ServerName www.example.com
ServerAlias example.com
ProxyPreserveHost On
ProxyPass "/api" http://localhost:5000/
ProxyPassReverse "/api" http://localhost:5000/
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) ws://localhost:5000/$1 [P]
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
SSLCertificateFile /etc/apache2/ssl/example_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCertificateChainFile /etc/apache2/ssl/example_com.ca-bundle
ErrorLog ${APACHE_LOG_DIR}example-error.log
CustomLog ${APACHE_LOG_DIR}example.log common
</VirtualHost>
当 Vue.js 应用程序尝试创建到 example.com/api/mainHub 的 websocket 连接时,会发生以下错误:
无法完成与服务器的协商:SyntaxError: Unexpected token H in JSON at position 0
它似乎将请求发送到正确的 URL,https://example.com/api/mainHub ,但无法建立连接。
我在 Linux 服务器上注意到的一件事是 POST 在路径中不包含 /api。
信息:Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 请求开始 HTTP/1.1 POST http://example.com//mainHub/negotiate text/plain;charset=UTF-8 0
这是我的 apache2 配置如何将请求路由到 /api 目录的问题吗?
编辑
我已经更改了我的 apache 配置以删除/
localhost:5000 末尾的额外内容 - 这允许外部连接到达正确的 API 路径。
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
<VirtualHost _default_:443>
DocumentRoot /var/www/example.com/dist/spa
ServerName www.example.com
ServerAlias example.com
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteRule /(.*) wss://localhost:5000$1 [P]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) https://localhost:5000$1 [P]
ProxyPreserveHost On
ProxyPass "/api" http://localhost:5000
ProxyPassReverse "/api" http://localhost:5000
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
SSLCertificateFile /etc/apache2/ssl/example_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCertificateChainFile /etc/apache2/ssl/example_com.ca-bundle
ErrorLog ${APACHE_LOG_DIR}example-error.log
CustomLog ${APACHE_LOG_DIR}example.log common
</VirtualHost>
现在的问题似乎与安全 websocket 升级有关。我尝试将 ws 升级更改为 wss,但仍然有问题。当客户端尝试建立 wss 连接时,会出现以下错误:
WebSocket 连接到“wss://example.com/api/mainHub?id=k1-_KxspgAQgIAhKroQBpQ”失败:WebSocket 握手期间出错:意外响应代码:502
我认为我的虚拟主机使用 HTTPS 升级 websocket 连接的方式有问题。
错误:无法启动传输“WebSockets”:null
解决方案
如果您的 .Net Core 应用程序正在侦听/api/
端口 5000,则将其添加到 ProxyPass 指令中:
ProxyPass "/api" http://localhost:5000/api
ProxyPassReverse "/api" http://localhost:5000/api
编辑:试试
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) ws://localhost:5000/$1 [P]
ProxyPreserveHost On
ProxyPass "/api" http://localhost:5000
ProxyPassReverse "/api" http://localhost:5000
推荐阅读
- node.js - NodeJS / Multer:如何用新文件替换目录中的现有文件
- mongodb - 索引对 db.find() 没有影响
- nativescript - Nativescript 7 angular 8 和 nativescript-google-maps-sdk 的问题
- postgresql - 托管图像并将其作为链接获取
- pine-script - 策略和研究中的价值图差异
- python - Tensorflow 2 对象检测不起作用?
- ios - 如何将入职视图显示为工作表?
- apache-superset - 显示原始记录时如何在 Apache Superset 表格图表中格式化数字
- javascript - Clean redux state when component unmount cancel all subscriptions and asynchronous tasks in a useEffect cleanup function
- python - When I have two different embed commands with different urls only one of them will work- Can someone help figure this out for me?