Wednesday, May 30, 2012

Mobile Redirect using htaccess


I have a website called



www.website.org



I have a mobile website called



m.website.org



I want to use an htaccess to automatically redirect the main website URL to the mobile version..



However, there is a link on the mobile version that points back to the main website called



www.website.org?noredirect=true



When I click the logo on the home page of the actual website it links to



www.website.org



I don't want the user to be allowed back to mobile accidentally by clicking on the logo on the main page. How can I accomplish this via htaccess without JavaSCript.



If not I am open-minded to alternate options.



EDIT



I think I am currently going to use this for sensing mobile redirect via htaccess




RewriteEngine On
RewriteBase /

RewriteCond %{HTTP_USER_AGENT} android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge\ |maemo|midp|mmp|opera\ m(ob|in)i|palm(\ os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows\ (ce|phone)|xda|xiino [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a\ wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r\ |s\ )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1\ u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp(\ i|ip)|hs\-c|ht(c(\-|\ |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac(\ |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt(\ |\/)|klon|kpt\ |kwc\-|kyo(c|k)|le(no|xi)|lg(\ g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-|\ |o|v)|zz)|mt(50|p1|v\ )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v\ )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-|\ )|webc|whit|wi(g\ |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-) [NC]
RewriteRule ^$ http://m.website.com [R,L]


Source: Tips4all

5 comments:

  1. I tested bits and pieces of the following, but not the complete rule set in its entirety, so if you run into trouble with it let me know and I'll dig around a bit more. However, assuming I got everything correct, you could try something like the following:

    RewriteEngine On

    # Check if this is the noredirect query string
    RewriteCond %{QUERY_STRING} (^|&)noredirect=true(&|$)
    # Set a cookie, and skip the next rule
    RewriteRule ^ - [CO=mredir:0:%{HTTP_HOST},S]

    # Check if this looks like a mobile device
    # (You could add another [OR] to the second one and add in what you
    # had to check, but I believe most mobile devices should send at
    # least one of these headers)
    RewriteCond %{HTTP:x-wap-profile} !^$ [OR]
    RewriteCond %{HTTP:Profile} !^$
    # Check if we're not already on the mobile site
    RewriteCond %{HTTP_HOST} !^m\.
    # Check to make sure we haven't set the cookie before
    RewriteCond %{HTTP:Cookie} !\smredir=0(;|$)
    # Now redirect to the mobile site
    RewriteRule ^ http://m.example.org%{REQUEST_URI} [R,L]

    ReplyDelete
  2. Tim Stone's solution is on the right track, but his initial rewriterule and and his cookie name in the final condition are different, and you can not write and read a cookie in the same request.

    Here is the finalized working code:

    RewriteEngine on
    RewriteBase /
    # Check if this is the noredirect query string
    RewriteCond %{QUERY_STRING} (^|&)m=0(&|$)
    # Set a cookie, and skip the next rule
    RewriteRule ^ - [CO=mredir:0:www.website.com]

    # Check if this looks like a mobile device
    # (You could add another [OR] to the second one and add in what you
    # had to check, but I believe most mobile devices should send at
    # least one of these headers)
    RewriteCond %{HTTP:x-wap-profile} !^$ [OR]
    RewriteCond %{HTTP:Profile} !^$ [OR]
    RewriteCond %{HTTP_USER_AGENT} "acs|alav|alca|amoi|audi|aste|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-" [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} "dang|doco|eric|hipt|inno|ipaq|java|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-" [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} "maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|opwv" [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} "palm|pana|pant|pdxg|phil|play|pluc|port|prox|qtek|qwap|sage|sams|sany" [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} "sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo" [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} "teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|w3cs|wap-|wapa|wapi" [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} "wapp|wapr|webc|winw|winw|xda|xda-" [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} "up.browser|up.link|windowssce|iemobile|mini|mmp" [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} "symbian|midp|wap|phone|pocket|mobile|pda|psp" [NC]
    RewriteCond %{HTTP_USER_AGENT} !macintosh [NC]

    # Check if we're not already on the mobile site
    RewriteCond %{HTTP_HOST} !^m\.
    # Can not read and write cookie in same request, must duplicate condition
    RewriteCond %{QUERY_STRING} !(^|&)m=0(&|$)

    # Check to make sure we haven't set the cookie before
    RewriteCond %{HTTP_COOKIE} !^.*mredir=0.*$ [NC]

    # Now redirect to the mobile site
    RewriteRule ^ http://m.website.com [R,L]

    ReplyDelete
  3. I modified Tim Stone's solution even further. This allows the cookie to be in 2 states, 1 for mobile and 0 for full. When the mobile cookie is set to 0 even a mobile browser will go to the full site.

    Here is the code:

    <IfModule mod_rewrite.c>
    RewriteBase /
    RewriteEngine On

    # Check if mobile=1 is set and set cookie 'mobile' equal to 1
    RewriteCond %{QUERY_STRING} (^|&)mobile=1(&|$)
    RewriteRule ^ - [CO=mobile:1:%{HTTP_HOST}]

    # Check if mobile=0 is set and set cookie 'mobile' equal to 0
    RewriteCond %{QUERY_STRING} (^|&)mobile=0(&|$)
    RewriteRule ^ - [CO=mobile:0:%{HTTP_HOST}]

    # cookie can't be set and read in the same request so check
    RewriteCond %{QUERY_STRING} (^|&)mobile=0(&|$)
    RewriteRule ^ - [S=1]

    # Check if this looks like a mobile device
    RewriteCond %{HTTP:x-wap-profile} !^$ [OR]
    RewriteCond %{HTTP_USER_AGENT} "android|blackberry|ipad|iphone|ipod|iemobile|opera mobile|palmos|webos|googlebot-mobile" [NC,OR]
    RewriteCond %{HTTP:Profile} !^$

    # Check if we're not already on the mobile site
    RewriteCond %{HTTP_HOST} !^m\.
    # Check to make sure we haven't set the cookie before
    RewriteCond %{HTTP:Cookie} !\mobile=0(;|$)
    # Now redirect to the mobile site
    RewriteRule ^ http://m.example.com%{REQUEST_URI} [R,L]
    </IfModule>

    ReplyDelete
  4. Or you may try this:

    ?php

    /**
    * Mobile Detect
    * @license http://www.opensource.org/licenses/mit-license.php The MIT License
    */
    class Mobile_Detect
    {
    protected $accept;
    protected $userAgent;
    protected $isMobile = false;
    protected $isAndroid = null;
    protected $isAndroidtablet = null;
    protected $isIphone = null;
    protected $isIpad = null;
    protected $isBlackberry = null;
    protected $isBlackberrytablet = null;
    protected $isOpera = null;
    protected $isPalm = null;
    protected $isWindows = null;
    protected $isWindowsphone = null;
    protected $isGeneric = null;
    protected $devices = array(
    "android" => "android.*mobile",
    "androidtablet" => "android(?!.*mobile)",
    "blackberry" => "blackberry",
    "blackberrytablet" => "rim tablet os",
    "iphone" => "(iphone|ipod)",
    "ipad" => "(ipad)",
    "palm" => "(avantgo|blazer|elaine|hiptop|palm|plucker|xiino)",
    "windows" => "windows ce; (iemobile|ppc|smartphone)",
    "windowsphone" => "windows phone os",
    "generic" => "(kindle|mobile|mmp|midp|pocket|psp|symbian|smartphone|treo|up.browser|up.link|vodafone|wap|opera mini)");

    public function __construct()
    {
    $this->userAgent = $_SERVER['HTTP_USER_AGENT'];
    $this->accept = $_SERVER['HTTP_ACCEPT'];

    if (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE']))
    {
    $this->isMobile = true;
    }
    elseif (strpos($this->accept, 'text/vnd.wap.wml') > 0 || strpos($this->accept, 'application/vnd.wap.xhtml+xml') > 0)
    {
    $this->isMobile = true;
    }
    else
    {
    foreach ($this->devices as $device => $regexp)
    {
    if ($this->isDevice($device))
    {
    $this->isMobile = true;
    }
    }
    }
    }

    /**
    * Overloads isAndroid() | isAndroidtablet() | isIphone() | isIpad() | isBlackberry() | isBlackberrytablet() | isPalm() | isWindowsphone() | isWindows() | isGeneric() through isDevice()
    *
    * @param string $name
    * @param array $arguments
    * @return bool
    */
    public function __call($name, $arguments)
    {
    $device = substr($name, 2);
    if ($name == "is" . ucfirst($device) && array_key_exists(strtolower($device), $this->devices))
    {
    return $this->isDevice($device);
    }
    else
    {
    trigger_error("Method $name not defined", E_USER_WARNING);
    }
    }

    /**
    * Returns true if any type of mobile device detected, including special ones
    * @return bool
    */
    public function isMobile()
    {
    return $this->isMobile;
    }

    protected function isDevice($device)
    {
    $var = "is" . ucfirst($device);
    $return = $this->$var === null ? (bool) preg_match("/" . $this->devices[strtolower($device)] . "/i", $this->userAgent) : $this->$var;
    if ($device != 'generic' && $return == true) {
    $this->isGeneric = false;
    }
    return $return;
    }

    ReplyDelete
  5. First, go to the following URL and download the mobile_detect.php file:

    http://code.google.com/p/php-mobile-detect/

    Insert the following code on your index or home page:

    <?php
    @include("Mobile_Detect.php");
    $detect = new Mobile_Detect();
    if ($detect->isMobile() && isset($_COOKIE['mobile']))
    {
    $detect = "false";
    }
    elseif ($detect->isMobile())
    {
    header("Location:http://www.yourmobiledirectory.com");
    }
    ?>

    ReplyDelete