2017-02-07 3 views
1

Ich habe eine ganze Website arbeiten mit HTTPS-Protokoll. Aber kürzlich habe ich ein sehr seltsames Verhalten von Yii bemerkt. Wenn ich eine Umleitung machen:Yii: seltsame Umleitung Verhalten (https -> http)

$this->redirect('/article/123456'); 

Es ist zunächst auf http Version der Seite-302 umleiten (I durch Header sehen):

HTTP://site.xyz/article/123456 

X-Powered-By: PHP/5.4.45-0 + deb7u2

Dann NGINX hat eine 301-Umleitung auf die https Version:

HTTPS://site.xyz/article/123456 

Warum es geschieht und wie Yü eine absolute URL bauen (immer gedacht, es verwendet relative sind)?

Antwort

1
/** 
    * Redirects the browser to the specified URL. 
    * @param string $url URL to be redirected to. Note that when URL is not 
    * absolute (not starting with "/") it will be relative to current request URL. 
    * @param boolean $terminate whether to terminate the current application 
    * @param integer $statusCode the HTTP status code. Defaults to 302. See {@link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html} 
    * for details about HTTP status code. 
    */ 
public function redirect($url,$terminate=true,$statusCode=302) 
    { 
     if(strpos($url,'/')===0 && strpos($url,'//')!==0) 
      $url=$this->getHostInfo().$url; 
     header('Location: '.$url, true, $statusCode); 
     if($terminate) 
      Yii::app()->end(); 
    } 

Source

die Notiz über die URL-Parameter prüfen:

@param string URL $ url umgeleitet werden. Beachten Sie, dass, wenn die URL nicht * absolut ist (nicht mit "/" beginnt), sie relativ zur aktuellen Anforderungs-URL ist.

jedoch in Ihrem Code die URL beginnt mit "/" so nach dem Quellcode, das nächste, was passieren würde, ist:. $ Url = $ this-> GetHostInfo() $ url;

wir also an der Quelle der GetHostInfo Funktion einen Blick:

public function getHostInfo($schema='') 
    { 
     if($this->_hostInfo===null) 
     { 
      if($secure=$this->getIsSecureConnection()) 
       $http='https'; 
      else 
       $http='http'; 
      if(isset($_SERVER['HTTP_HOST'])) 
       $this->_hostInfo=$http.'://'.$_SERVER['HTTP_HOST']; 
      else 
      { 
       $this->_hostInfo=$http.'://'.$_SERVER['SERVER_NAME']; 
       $port=$secure ? $this->getSecurePort() : $this->getPort(); 
       if(($port!==80 && !$secure) || ($port!==443 && $secure)) 
        $this->_hostInfo.=':'.$port; 
      } 
     } 
     if($schema!=='') 
     { 
      $secure=$this->getIsSecureConnection(); 
      if($secure && $schema==='https' || !$secure && $schema==='http') 
       return $this->_hostInfo; 
      $port=$schema==='https' ? $this->getSecurePort() : $this->getPort(); 
      if($port!==80 && $schema==='http' || $port!==443 && $schema==='https') 
       $port=':'.$port; 
      else 
       $port=''; 
      $pos=strpos($this->_hostInfo,':'); 
      return $schema.substr($this->_hostInfo,$pos,strcspn($this->_hostInfo,':',$pos+1)+1).$port; 
     } 
     else 
      return $this->_hostInfo; 
    } 

Ich würde Ihnen raten, zu überprüfen, ob die erste Bedingung true zurück (während ich finde es nicht wahrscheinlich, dass _hostInfo gewesen definiert) und das Ergebnis der Funktion $ this-> getIsSecureConnection() überprüfen.

+0

Danke, ich habe das Problem gefunden. Server setzt $ _SERVER ['HTTPS'] (https://github.com/yiisoft/yii/blob/1.1.17/framework/web/CHTtpRequest.php#L581) nicht und es verursacht dieses Verhalten. Als Workaround stelle ich es manuell in * index.php * ein und suche nach einer dauerhaften Lösung. –

+1

Nun ... es ist eine seltenere Situation, aber wenn Sie den nächsten Schritt folgen würden, wäre es die getIsSecureConnection Funktion zu überprüfen (https://github.com/yiisoft/yii/blob/04f97932ddfbf9c5bdaae0a6a41b851544704a27/framework/web/CHTtpRequest .php # L581) Sie wären also zu dem gleichen Schluss gekommen. Viel Glück. –