在配置本地环境以在 Nginx 前使用 Varnish 时,让我印象深刻的一件事是应用程序重定向开始表现得很奇怪。从产品视图添加产品进行比较会将我重定向到基本 URL,而不是返回到产品视图(引荐来源网址)。所以我开始深入研究核心,看看到底发生了什么。
app/code/core/Mage/Core/Controller/Varien/Action.php:773
_getRefererUrl 方法在请求 URI 或请求标头中查找任何引用 URL。由于某种原因,$refererUrl 没有作为_isUrlInternal 传递,这使得它回退到基本 URL。
/**
* Identify referer url via all accepted methods (HTTP_REFERER, regular or base64-encoded request param)
*
* @return string
*/
protected function _getRefererUrl()
{
$refererUrl = $this->getRequest()->getServer('HTTP_REFERER');
if ($url = $this->getRequest()->getParam(self::PARAM_NAME_REFERER_URL)) {
$refererUrl = $url;
}
if ($url = $this->getRequest()->getParam(self::PARAM_NAME_BASE64_URL)) {
$refererUrl = Mage::helper('core')->urlDecode($url);
}
if ($url = $this->getRequest()->getParam(self::PARAM_NAME_URL_ENCODED)) {
$refererUrl = Mage::helper('core')->urlDecode($url);
}
$refererUrl = Mage::helper('core')->escapeUrl($refererUrl);
if (!$this->_isUrlInternal($refererUrl)) {
$refererUrl = Mage::app()->getStore()->getBaseUrl();
}
return $refererUrl;
}
app/code/core/Mage/Core/Controller/Varien/Action.php:799
Magento 在这里寻找(基准 URL)字符串 http://domain.com/ 在(引用 URL)http://domain.com:8080/any/url.html 中的位置,由于 Nginx 正在侦听的端口号(在 Varnish 后面),因此永远找不到该位置。
/**
* Check url to be used as internal
*
* @param string $url
* @return bool
*/
protected function _isUrlInternal($url)
{
if (strpos($url, 'http') !== false) {
/**
* Url must start from base secure or base unsecure url
*/
if ((strpos($url, Mage::app()->getStore()->getBaseUrl()) === 0)
|| (strpos($url, Mage::app()->getStore()->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK, true)) === 0)
) {
return true;
}
}
return false;
}
app/code/core/Mage/Core/Helper/Url.php:37
在 Magento 中构建当前 URL 时(出于某种奇怪的原因)添加了该端口号。
/**
* Retrieve current url
*
* @return string
*/
public function getCurrentUrl()
{
$request = Mage::app()->getRequest();
$port = $request->getServer('SERVER_PORT');
if ($port) {
$defaultPorts = array(
Mage_Core_Controller_Request_Http::DEFAULT_HTTP_PORT,
Mage_Core_Controller_Request_Http::DEFAULT_HTTPS_PORT
);
$port = (in_array($port, $defaultPorts)) ? '' : ':' . $port;
}
$url = $request->getScheme() . '://' . $request->getHttpHost() . $port . $request->getServer('REQUEST_URI');
return $url;
}
让重定向再次起作用
在不改变应用程序的情况下,您的网络服务器 (Nginx) 需要监听端口 80(或 443),同时仍将 Varnish 保持在其前面。这可以通过使用 iptables 来完成。