我见过如何使用反向代理正确处理相对 URL- 然而我很难理解这一点(并将其应用到我的问题中),希望有人能帮助我。
假设我的服务器上有 Ubuntu 20.04 作为服务器操作系统example.com
。
然后我安装https://github.com/hartwork/jawanndenn在服务器上,并运行它 - 此应用程序默认在端口 8080 上运行;并且我可以通过运行以下命令确认它在服务器本身上运行:
wget -O- http://127.0.0.1:8080
到目前为止一切顺利。现在,我想要的是:不是访问https://example.com:8080
来访问此应用程序,而是访问https://example.com/jaw
- 我通常称之为/jaw
“子目录”,但可能更准确地说是相对 URL。换句话说,如果我正确理解了术语,https://example.com/jaw
将反向代理到https://example.com:8080
。
因此,我尝试在<VirtualHost *:443>
我的.conf
文件定义中执行此操作:
<Location /jaw>
Options -Multiviews -Indexes
RewriteEngine On
ProxyPass http://127.0.0.1:8080
ProxyPassReverse http://127.0.0.1:8080
SetOutputFilter proxy-html
ProxyHTMLURLMap http://127.0.0.1:8080
</Location>
RewriteRule ^/jaw$ /jaw/ [R]
这是可行的——应用程序的起始页已经加载;但是大量的资源(.css、.js)无法加载;打开浏览器中的控制台,我可以看到一堆 404 请求:
https://example.com/static/3rdparty/jquery-3.5.1/jquery-3.5.1.min.js
https://example.com/static/3rdparty/roboto-20/css/roboto.css
...
因此,我的猜测是,有一些 .js 文件或类似文件,只是想加载/static/...
-> 如果从“端口”地址调用,它们就会映射到http://127.0.0.1:8080/static/...
并且一切都会很好;但是现在,由于我们被代理了:
- 浏览器请求
https://example.com/jaw
- Apache 获取该信息,并将其转发到
https://example.com:8080
应用程序监听的位置 - 应用程序返回文件(.js),其中包含以下形式的链接
/static/...
- 一旦这些内容返回到浏览器,它们将被解释为
https://example.com/static/...
- 然后被用作对服务器的请求,而服务器则无法找到它们
我也尝试过摆脱<Location>
上面的整个代码片段,而只在节点中使用它<VirtualHost *:443>
:
ProxyPass /jaw/ http://127.0.0.1:6789/
ProxyPassReverse /jaw/ http://127.0.0.1:6789/
与之前发生的情况完全相同 - 第一页已加载,所有其他资源显然都引用了它,/static/...
但它们都显示 404。
最后,我也摆脱了上述陈述,并使用了这个:
ProxyPass /jaw/ http://127.0.0.1:8080
ProxyHTMLURLMap http://127.0.0.1:8080 /jaw
<Location /jaw/>
ProxyPassReverse /
ProxyPassReverse http://127.0.0.1:8080
ProxyHTMLEnable On
ProxyHTMLURLMap / /jaw/
</Location>
这具有完全相同的行为 - 第一页加载,资源失败 - 除了资源现在在浏览器控制台中列出如下:
https://example.com/jaw/static/3rdparty/jquery-3.5.1/jquery-3.5.1.min.js
https://example.com/jaw/static/3rdparty/roboto-20/css/roboto.css
...
... 并出现 502 代理错误。因此进行了一些重写,但仍然有些不对劲。
所以我的问题是 - 我该如何告诉 Apache,代理一切从 127.0.0.1:8080 上的应用程序,到显示为“子目录”的内容(相对 URL?这里/jaw
)?
编辑:事实证明,502 代理错误是由于:
AH00898: DNS lookup failure for: 127.0.0.1:6789static returned by /poll/static/js/html.js
...显然缺少了一个斜线;所以结果是这样的:
ProxyPass /jaw/ http://127.0.0.1:8080/
ProxyHTMLURLMap http://127.0.0.1:8080/ /jaw/
<Location /jaw/>
ProxyPassReverse /
ProxyPassReverse http://127.0.0.1:8080/
ProxyHTMLEnable On
ProxyHTMLURLMap / /jaw/
</Location>
...实际上确实有效 - 在大多数情况下(资源/static
);但是,有一个调用/data
没有得到处理...所以它仍然是一个悬而未决的问题(对我来说)如何代理“一切“
答案1
使用正确的基本 URL 配置后端服务器。这比在代理上强制重写要容易得多。
设置应为JAWANNDENN_URL_PREFIX
。只需将其设置为/jaw
,所有 URL 都应正确生成。
即使没有 ProxyHTMLURLMap 和 OutputFilter,您的第一个示例也应该可以工作。