LoginSignup
7
9

More than 5 years have passed since last update.

スマホや携帯の標準ブラウザをnginxで振り分ける

Posted at

スマホや携帯の標準ブラウザを振り分ける

古いAndroidのブラウザは振り分けないといけない状況になる場合

「HTML4時代に構築された携帯電話向け自社サービスをHTML5ベースのスマホ向けサービスに切り替えよう」という話が社内で出た時の小ネタ。

スマホと一言で言ってもiPhoneなのかAndroidなのかで諸々検討事項はあるものの、iPhoneは多少古めの機種でも概ねバージョンアップされているのであまり問題は起きないと期待される。
ほとんどの場合問題となるのはAndroidではないだろうか。
Androidは端末の画面サイズとブラウザのHTML5対応状況がややこしいというのは割と知られているのではないかと思うが、中でも事態をややこしくしているのは「Androidの4.2以前と4.3以降で標準ブラウザが変わったこと」ではないかと思われる。
つまり、4.2までの標準ブラウザは「AOSPブラウザー」、4.3以降は「Chrome(ベースの)ブラウザー」であるという問題である。
4.3以降であれば実質的にChromeなのでいわゆる普通のHTML5で問題は無いのだが、4.2以前ではAOSPベースでメンテナンスが行き届いていないためHTML5対応が不十分である可能性があり、そのため別サイト(というかHTML4ベースの既存サイト)に誘導する必要があると考えられる。

これらを踏まえて、弊社環境では以下のようになる。

機種 振り分け先
フィーチャーフォン HTML4ベースの旧サイト
Android 4.2以前 HTML4ベースの旧サイト
Android 4.3以降 HTML5ベースの新サイト
iPhone HTML5ベースの新サイト

Android 4.4.2の混乱

それでは実際に振り分ける判断基準をどうするかといった場合、一般的にはUser-Agentを見て振り分けることになると思われる。
単純に考えればAndroidのバージョン情報を拾って…となるのだがここにも一つ問題点がある。
一部のスマートフォンではAndroid 4.2から4.4へバージョンアップが行われた際に、「標準ブラウザがAOSPのままになっている」機種があるのである。
そのため、「単純にAndroid 4.3を境目にして振り分ける」という事が困難になっている。

例 : HTC J one (HTL22) と isai (LGL22)

HTC J one (HTL22)では標準搭載のブラウザは以下のようになる。

Androidのversion 標準ブラウザ Chrome
4.4.2(OSアップデート後) AOSP Chrome
4.2.2(出荷時初期状態) AOSP Chrome

対して、isai (LGL22)では標準搭載のブラウザは以下のようになる。

Androidのversion 標準ブラウザ Chrome
4.4.2(OSアップデート後) Chrome Chrome
4.2.2(出荷時初期状態) AOSP Chrome

Chromeのバージョンで判断する

上記の理由によりAndroidのバージョンを元に判断することが難しいため、Chromeのバージョンを組み合わせて判断することを考える。
Chromeのバージョン閾値をどこに設定するかという問題があるが、判断基準としては以下のいずれかが妥当な線ではないかと考える。

最初期のAndroid向けChrome

AndroidにデフォルトでChromeが組み込まれ始めたのは2012年冬モデルのあたりである。
この頃のChromeのバージョンはChrome/18

Android 4.4の標準ブラウザになった頃のChrome

Androidの標準ブラウザがChromeに切り替わり始めたのは2014年夏モデルのあたりである。
この頃のChromeのバージョンはChrome/30

Android 4.0でサポートされる最終version

2015年に少し話題に上がった「Android 4.0 以前のバージョンに対してのChromeのサポートの打ち切り」。
対象となるChromeのバージョンは42とされているのでChrome/42

フィーチャーフォンとiPhone

フィーチャーフォンについてはキャリア名(DoCoMo or KDDI or Vodafone or Softbank)が入っている事が知られているため、これで判断できる。
iPhoneについては"iPhone"と入っている事が知られているため、これで判断できる。
iPadなども対象とする場合は、"Mac OS X"を拾った方かもしれない。

振り分け条件

機種 振り分け先 User-Agentの識別文字列
フィーチャーフォン HTML4ベースの旧サイト DoCoMo または KDDI または Vodafone または Softbank
Android 4.2以前 HTML4ベースの旧サイト Android のみ
Android 4.3以降 HTML4ベースの新サイト Android かつ Chrome/30(未満)
Android 4.3以降 HTML5ベースの新サイト Android かつ Chrome/30(以上)
iPhone HTML5ベースの新サイト iPhone のみ

nginxでの振り分け

nginxのリバースプロキシ機能で振り分ける場合は以下のような設定になる

# ベースはPC用サイトとする
set $environment PC;
# ガラケー用判定ロジック
if ($http_user_agent ~ (DoCoMo|KDDI|Vodafone|Softbank)) {
  set $environment cellular;
}
# AOSP
if ($http_user_agent ~ ^(?!.*Chrome).*(?=Android).*$) {
  set $environment androidaosp;
}
# Android向けChromeの Chrome/30 未満(29以下)
if ($http_user_agent ~ Android.*Chrome\/[0-2]+[0-9]) {
  set $environment androidoldchrome;
}
# Android向けChromeの Chrome/30 以降
if ($http_user_agent ~ Android.*Chrome\/[3-9]+[0-9]) {
  set $environment androidchrome;
}
# iPhone向け
if ($http_user_agent ~ iPhone) {
  set $environment iphone;
}

location / {
    if ($environment = PC) {
        root /var/www/html/pc;
    }
    if ($environment = cellular) {
        root /var/www/html/cellular;
    }
    if ($environment = androidaosp) {
        root /var/www/html/android/aosp;
    }
    if ($environment = androidoldchrome) {
        root /var/www/html/android/oldchrome;
    }
    if ($environment = androidchrome) {
        root /var/www/html/android/chrome;
    }
    if ($environment = iphone) {
        root /var/www/html/iphone;
    }
}
  • 上記の例ではif文を使用しているが本来if文は使うべきではないとの事。
  • 動作確認は nginx 1.10.1 / CentOS7 のみ
    • クライアントは実機の用意ができなかったのでPC用ChromeのUser-Agent偽装を用いて確認
  • 今回はとりあえずChrome/30を区切りとしたけれどプロジェクトでは要調整

参考資料

atmarkIT - Tech TIPS:Android OSと「ブラウザ」、Chrome、アプリ内ブラウザーの関係をまとめる
ITメディアエンタープライズ - Google、Android 4.0向けChromeのサポート打ち切りへ
nginx - If Is Evil

7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9