问题
I'm having trouble figuring this one out. I'm trying to direct mobile traffic to the mobile version of a website via HTACCESS User-Agent sniffing, like so:
RewriteCond %{HTTP_USER_AGENT} (android|blackberry|ipad|iphone|ipod|iemobile|mini|mobi|palmos|webos|googlebot\-mobile) [NC]
RewriteCond %{HTTP_HOST} ^mobile\.mywebsite\.com$
RewriteRule ^([aA0-zZ9\-\/]*)/([^/]*)$ /index.php?page=$1&q=$2&q2=$3&setview=mobile [L,QSA]
The string mini|mobi
is where the Opera Mini browser should be detected. However, this does NOT happen. I've also changed that string to opera m
and other variations. Still no luck.
This rewrite condition appears to work with other mobile browsers, but not Opera, and I don't understand why. Even the second condition, which checks for an explicit pointer to the mobile.
subdomain also fails to deliver the mobile content.
I'm not an HTACCESS guru, so my first guess is that my syntax is wrong. But why does this work on other mobile browsers and not Opera Mini?
Thanks for looking!
UPDATE: 2012-06-08
I actually resorted to a different method by using PHP to check headers. For some reason my HTACCESS file did not detect certain header information. Even though karlcow's answer would validate, I was having trouble getting the iPhone and third-party Android browsers to validate. It wasn't until a page was passed to the PHP interpreter that I was able to read the information. I guess I just don't understand how that works.
Anyway, I borrowed code from an Internet search that I placed into a library function:
function get_device_view() {
$view='desktop';
if(preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone|android)/i', strtolower($_SERVER['HTTP_USER_AGENT'])))
$view='mobile';
if((strpos(strtolower($_SERVER['HTTP_ACCEPT']),'application/vnd.wap.xhtml+xml')>0) || ((isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE']))))
$view='mobile';
$mobile_ua=strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4));
$mobile_agents=array(
'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
'wapr','webc','winw','winw','xda ','xda-');
if(in_array($mobile_ua,$mobile_agents))
$view='mobile';
if (strpos(strtolower($_SERVER['ALL_HTTP']),'OperaMini')>0)
$view='mobile';
if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows')>0)
$view='desktop';
return $view;
}
This function is called as part of a strapper process for the website so that before anything is output, the $view
is returned so that appropriate pages and stylesheets are loaded.
Additionally, I modified my HTACCESS file to contain the following:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_COOKIE} !((^|;\s*)DD_VIEW=([^;]+))
RewriteCond %{HTTP_HOST} mobile\.buffalosbigdeal\.com
RewriteRule ^([aA0-zZ9\-\/]*)/*([^/]*)$ /index.php?page=$1&q=$2&q2=$3&setview=mobile [L,QSA]
As you can see I'm only redirecting explicit calls for the mobile. subdomain, and those not containing a cookie which retains the $view
set during the strapper process.
My original intent was to perform browser detection exclusively using HTACCESS; because of simplicity and under premise of mod_rewrite's power. But in my frustration, and to meet the deadline, I compromised by settling for a more chunky method that may require more maintenance in the future.
Lesson learned: Build responsive websites based on browser capabilities (ie: resolution, touch, and DOM level), and do not rely heavily on user-agent strings. Have we yet a solution like this?
Thanks for looking.
回答1:
Note that the pattern of Opera Mini string is
Opera/9.80 (J2ME/MIDP; Opera Mini/$CLIENT_VERSION/$SERVER_VERSION; U; $LANGUAGE) Presto/$PRESTO_VERSION
Mini is with an uppercase M. Hmm but you put NC which is for nocase, so that's not it. Just to be sure could you try
RewriteCond %{HTTP_USER_AGENT} (android|blackberry|ipad|iphone|ipod|iemobile|mobi|palmos|webos|googlebot\-mobile) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} Opera\ Mini
回答2:
Should it be if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'operamini')>0)
or should it be if (strpos(strtolower($_SERVER['ALL_HTTP']),'operamini')>0)
I get a debug error using ALL_HTTP, but the error goes away when I use HTTP_USER_AGENT
Here is the debug error, as follows: Debug Notice: Undefined index: ALL_HTTP in header.php on line 29
来源:https://stackoverflow.com/questions/10935710/mobile-browser-detection-with-htaccess-fails-with-opera-mini