我正在尝试使用 Docker 在 Apache2 反向代理后面建立一个 Shopware 网站。由于 Shopware 软件出于某种原因将其后端主机“http://127.0.0.1:18084“进入它发送到浏览器的 JavaScript,我尝试使用 mod_substitute 将其替换为外部主机名:
ProxyPass / http://127.0.0.1:18084/
ProxyPassReverse / http://127.0.0.1:18084/
<Location />
AddOutputFilterByType SUBSTITUTE text/html application/javascript
Substitute "s!127.0.0.1:18084!my.real.domain.de!in"
</Location>
这确实有效,即主机名被替换。但是,一些 JavaScript 文件使用分块编码发送,这会导致浏览器中出现问题(来自 JS 控制台的输出):
GET http://my.real.domain.de/engine/Library/ExtJs/ext-all.js?201611281529
net::ERR_INCOMPLETE_CHUNKED_ENCODING
我首先想到的是替换会弄乱块长度,但当我删除该Substitute
行时也会出现问题。只要有一行AddOutputFilterByType
内容类型application/javascript
就会导致问题。
反向代理Apache是2.4.7版本,后端apache是2.4.18。
是我做错了什么,还是这是 Apache 的问题?(Apache 反向代理在 2.2 中弄乱了最后一个空块,但我认为现在应该已经解决了)
更新:
ezra_s 指出我应该确保浏览器缓存不会影响这一点。我使用以下方法进行了检查curl
:
主机配置文件中没有这行代码时AddOutputFilterByType
,Substitute
JS 文件会被完全传输(大约 1259k 字节)。如果只AddOutputFilterByType
启用这行代码,我会得到以下输出:
here:~ tos$ curl http://my.real.domain.de/engine/Library/ExtJs/ext-all.js?201611281529
/*
This file is part of Ext JS 4.1
Copyright (c) 2011-2012 Sencha Inc
Contact: http://www.sencha.com/contact
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.
Build date: 2012-07-04 21:11:01 (65ff594cd80b9bad45df640c22cc0adb52c95a7b)
*/
curl: (18) transfer closed with outstanding read data remaining
here:~ tos$
这显示了类似的行为,但表明不仅缺少末尾块,而且缺少除第一个块之外的所有块。
我用 tcpdump 检查了这一点。它也显示只有一个块到达。
更新 2:
这似乎是 mod_substitute 的问题。在我的反向代理的错误日志中,我发现了以下行:
[Fri Dec 30 11:44:03.934066 2016] [substitute:error] [pid 2725] [client xxx.xxx.xxx.xxx:56492] AH01328: Line too long, URI /engine/Library/ExtJs/ext-all.js
看起来 javascript 被打包成了一行长代码,对于 来说太长了mod_substitute
,甚至在定义替换之前就失败了。
如果我找不到这个问题的解决方案,我想我会将其重新作为一个新问题提出。
答案1
我遇到了同样的问题并在这里找到了答案:
https://bz.apache.org/bugzilla/show_bug.cgi?id=56176
mod_substitute
每行使用最大长度限制。如果您的(混乱的)页面中有一行超过该长度,模块将突然结束响应。
从 2.4.11 开始,他们添加了一个新参数来控制此行大小限制。
http://httpd.apache.org/docs/2.4/mod/mod_substitute.html#substitutemaxlinelength
答案2
默认情况下,mod_substitute
最大行长度为一兆字节。
对于您来说,您必须增加最大行长度值(例如增加到 2 兆字节)。
SubstituteMaxLineLength 2m
该指令SubstituteMaxLineLength
自版本起可用2.4.11。
在您的示例中:
<Location />
AddOutputFilterByType SUBSTITUTE text/html application/javascript
SubstituteMaxLineLength 2m
Substitute "s!127.0.0.1:18084!my.real.domain.de!in"
</Location>